All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
@ 2017-01-17 15:27 stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value stefan.herbrechtsmeier at weidmueller.com
                   ` (10 more replies)
  0 siblings, 11 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>


The old platform clock driver use a dynamic array which is filled at
every boot with static clock tree information and unused clock rates.
This needs much memory and complicates the strip down for the SPL.
The new clock framework driver contains the tree information in
functions and reads clock rates on demand.

This series depends on patch 'mmc: sdhci: Distinguish between base clock
and maximum peripheral frequency'


Changes in v2:
- Rebase
- Group ifndef CONFIG_SPL_BUILD inside switch case of zynq_clk_get_register()
- Put same switch case code together in zynq_clk_get_*_pll()
- Replace ZYNQ_CLKMUX_SEL_* by there numbers
- Return error code and add debug message for unknown gem eimo rx clock source
- Correct zynq_clk_calc_peripheral_two_divs() parameter indetation
- Add support for unknown clock rate to soc_clk_dump()
- Return a error and print a debug message if a gem emio rx clock
  source is unknown
- Correct the checks for valid clock objects
- Add patch to determine base clock frequency of zynq mmc driver via
  clock framework
- Add patch to add fdt max-frequency support to zynq mmc driver

Stefan Herbrechtsmeier (10):
  net: zynq: Don't overwrite gem_rclk_ctrl with default value
  net: zynq: Add clk framework support to zynq ethernet driver
  zynq: Add clk framework support to zynq timer
  zynq: Move static clock names into separate array
  zynq: Remove zynq_clk_get_name function
  clk: zynq: Add zynq clock framework driver
  zynq: Move zynq to clock framework
  clk: zynq: Add optional ethernet emio clock source support
  mmc: zynq: Determine base clock frequency via clock framework
  mmc: zynq: Add fdt max-frequency support

 arch/arm/Kconfig                             |   3 +
 arch/arm/dts/zynq-7000.dtsi                  |   2 +
 arch/arm/include/asm/arch-zynqmp/sys_proto.h |   7 -
 arch/arm/mach-zynq/clk.c                     | 690 +++------------------------
 arch/arm/mach-zynq/cpu.c                     |   1 -
 arch/arm/mach-zynq/include/mach/clk.h        |   6 -
 arch/arm/mach-zynq/include/mach/sys_proto.h  |   1 -
 arch/arm/mach-zynq/slcr.c                    |  29 --
 arch/arm/mach-zynq/timer.c                   |  23 +
 drivers/clk/Kconfig                          |   8 +
 drivers/clk/Makefile                         |   1 +
 drivers/clk/clk_zynq.c                       | 488 +++++++++++++++++++
 drivers/mmc/zynq_sdhci.c                     |  33 +-
 drivers/net/zynq_gem.c                       |  28 +-
 drivers/serial/serial_zynq.c                 |   6 +-
 include/configs/topic_miami.h                |   2 -
 include/configs/zynq_zybo.h                  |   3 -
 scripts/config_whitelist.txt                 |   1 -
 18 files changed, 634 insertions(+), 698 deletions(-)
 create mode 100644 drivers/clk/clk_zynq.c

-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-18 21:48   ` Joe Hershberger
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 02/10] net: zynq: Add clk framework support to zynq ethernet driver stefan.herbrechtsmeier at weidmueller.com
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

The gem[0-1]_rclk_ctrl registers control the source of the rx clock,
control and data signals and configure via ps7_init function. Don't
overwrite the register with the default value.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
---

Changes in v2: None

 arch/arm/mach-zynq/slcr.c |  7 -------
 drivers/net/zynq_gem.c    | 15 +++++----------
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index 2d3bf2a..c1129cd 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -140,13 +140,6 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
 	if (ret)
 		goto out;
 
-	if (gem_id) {
-		/* Configure GEM_RCLK_CTRL */
-		writel(1, &slcr_base->gem1_rclk_ctrl);
-	} else {
-		/* Configure GEM_RCLK_CTRL */
-		writel(1, &slcr_base->gem0_rclk_ctrl);
-	}
 	udelay(100000);
 out:
 	zynq_slcr_lock();
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 6dd87cf..872e4f8 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -175,7 +175,6 @@ struct zynq_gem_priv {
 	u32 rxbd_current;
 	u32 rx_first_buf;
 	int phyaddr;
-	u32 emio;
 	int init;
 	struct zynq_gem_regs *iobase;
 	phy_interface_t interface;
@@ -457,15 +456,13 @@ static int zynq_gem_init(struct udevice *dev)
 		break;
 	}
 
-	/* Change the rclk and clk only not using EMIO interface */
-	if (!priv->emio)
 #ifndef CONFIG_CLK_ZYNQMP
-		zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
-					ZYNQ_GEM_BASEADDR0, clk_rate);
+	zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
+				ZYNQ_GEM_BASEADDR0, clk_rate);
 #else
-		ret = clk_set_rate(&priv->clk, clk_rate);
-		if (IS_ERR_VALUE(ret))
-			return -1;
+	ret = clk_set_rate(&priv->clk, clk_rate);
+	if (IS_ERR_VALUE(ret))
+		return -1;
 #endif
 
 	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
@@ -689,7 +686,6 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
 	pdata->iobase = (phys_addr_t)dev_get_addr(dev);
 	priv->iobase = (struct zynq_gem_regs *)pdata->iobase;
 	/* Hardcode for now */
-	priv->emio = 0;
 	priv->phyaddr = -1;
 
 	priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob,
@@ -707,7 +703,6 @@ static int zynq_gem_ofdata_to_platdata(struct udevice *dev)
 	}
 	priv->interface = pdata->phy_interface;
 
-	priv->emio = fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "xlnx,emio");
 
 	printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase,
 	       priv->phyaddr, phy_string_for_interface(priv->interface));
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 02/10] net: zynq: Add clk framework support to zynq ethernet driver
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-18 21:50   ` Joe Hershberger
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 03/10] zynq: Add clk framework support to zynq timer stefan.herbrechtsmeier at weidmueller.com
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

If available use the clock framework to set the tx clock rate of the
zynq ethernet controller.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
---

Changes in v2:
- Rebase

 arch/arm/include/asm/arch-zynqmp/sys_proto.h |  7 -------
 drivers/net/zynq_gem.c                       | 22 +++++++++++++++-------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index 8c54fce..7b11895 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -8,13 +8,6 @@
 #ifndef _ASM_ARCH_SYS_PROTO_H
 #define _ASM_ARCH_SYS_PROTO_H
 
-#ifndef CONFIG_CLK_ZYNQMP
-/* Setup clk for network */
-static inline void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
-{
-}
-#endif
-
 int zynq_slcr_get_mio_pin_status(const char *periph);
 
 unsigned int zynqmp_get_silicon_version(void);
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 872e4f8..8c5c55a 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -181,7 +181,7 @@ struct zynq_gem_priv {
 	struct phy_device *phydev;
 	int phy_of_handle;
 	struct mii_dev *bus;
-#ifdef CONFIG_CLK_ZYNQMP
+#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	struct clk clk;
 #endif
 };
@@ -456,13 +456,21 @@ static int zynq_gem_init(struct udevice *dev)
 		break;
 	}
 
-#ifndef CONFIG_CLK_ZYNQMP
+#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
+	ret = clk_set_rate(&priv->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) {
+		dev_err(dev, "failed to enable tx clock\n");
+		return ret;
+	}
+#else
 	zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
 				ZYNQ_GEM_BASEADDR0, clk_rate);
-#else
-	ret = clk_set_rate(&priv->clk, clk_rate);
-	if (IS_ERR_VALUE(ret))
-		return -1;
 #endif
 
 	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
@@ -636,7 +644,7 @@ 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);
 
-#ifdef CONFIG_CLK_ZYNQMP
+#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get clock\n");
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 03/10] zynq: Add clk framework support to zynq timer
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 02/10] net: zynq: Add clk framework support to zynq ethernet driver stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 04/10] zynq: Move static clock names into separate array stefan.herbrechtsmeier at weidmueller.com
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

If available use the clock framework to calculate the clock rate of the
zynq timer.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
---

Changes in v2: None

 arch/arm/mach-zynq/timer.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
index 8ff82dc..0335cbe 100644
--- a/arch/arm/mach-zynq/timer.c
+++ b/arch/arm/mach-zynq/timer.c
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2017 Weidm?ller Interface GmbH & Co. KG
+ * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+ *
  * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
  * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
  *
@@ -25,8 +28,10 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <clk.h>
 #include <common.h>
 #include <div64.h>
+#include <dm.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/clk.h>
@@ -56,6 +61,26 @@ int timer_init(void)
 			(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
 			SCUTIMER_CONTROL_ENABLE_MASK;
 
+#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
+	struct udevice *dev;
+	struct clk clk;
+	int ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+		DM_GET_DRIVER(zynq_clk), &dev);
+	if (ret)
+		return ret;
+
+	clk.id = cpu_6or4x_clk;
+	ret = clk_request(dev, &clk);
+	if (ret < 0)
+		return ret;
+
+	gd->cpu_clk = clk_get_rate(&clk);
+
+	clk_free(&clk);
+#endif
+
 	gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
 
 	/* Load the timer counter register */
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 04/10] zynq: Move static clock names into separate array
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (2 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 03/10] zynq: Add clk framework support to zynq timer stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 05/10] zynq: Remove zynq_clk_get_name function stefan.herbrechtsmeier at weidmueller.com
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

The clock names are static and correspond to the clock id. Separate
them from the dynamic filled clock array.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
Reviewed-by: Michal Simek <michal.simek@xilinx.com>
---

Changes in v2: None

 arch/arm/mach-zynq/clk.c | 121 +++++++++++++++++++++++------------------------
 1 file changed, 60 insertions(+), 61 deletions(-)

diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index 40383c1..7bff964 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -58,7 +58,6 @@ struct zynq_clk_ops {
 
 /**
  * struct clk:
- * @name:	Clock name
  * @frequency:	Currenct frequency
  * @parent:	Parent clock
  * @flags:	Clock flags
@@ -66,7 +65,6 @@ struct zynq_clk_ops {
  * @ops:	Clock operations
  */
 struct clk {
-	char		*name;
 	unsigned long	frequency;
 	enum zynq_clk	parent;
 	unsigned int	flags;
@@ -77,6 +75,20 @@ struct clk {
 
 static struct clk clks[clk_max];
 
+static const char * const clk_names[clk_max] = {
+	"armpll", "ddrpll", "iopll",
+	"cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x",
+	"ddr2x", "ddr3x", "dci",
+	"lqspi", "smc", "pcap", "gem0", "gem1",
+	"fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
+	"sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma",
+	"usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper",
+	"sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper",
+	"can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper",
+	"uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper",
+	"smc_aper", "swdt", "dbg_trc", "dbg_apb"
+};
+
 /**
  * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
  * @srcsel:	Mux select value
@@ -140,14 +152,12 @@ static void init_ddr_clocks(void)
 	/* DDR2x */
 	clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
 	clks[ddr2x_clk].parent = ddrpll_clk;
-	clks[ddr2x_clk].name = "ddr_2x";
 	clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
 	clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
 
 	/* DDR3x */
 	clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
 	clks[ddr3x_clk].parent = ddrpll_clk;
-	clks[ddr3x_clk].name = "ddr_3x";
 	clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
 	clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
 
@@ -159,7 +169,6 @@ static void init_ddr_clocks(void)
 	clks[dci_clk].parent = ddrpll_clk;
 	clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
 			DIV_ROUND_CLOSEST(prate, div0), div1);
-	clks[dci_clk].name = "dci";
 
 	gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
 }
@@ -181,24 +190,20 @@ static void init_cpu_clocks(void)
 	clks[cpu_6or4x_clk].parent = parent;
 	clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
 			zynq_clk_get_rate(parent), div);
-	clks[cpu_6or4x_clk].name = "cpu_6or4x";
 
 	clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
 	clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
 	clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
-	clks[cpu_3or2x_clk].name = "cpu_3or2x";
 
 	clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
 	clks[cpu_2x_clk].parent = cpu_6or4x_clk;
 	clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
 			(2 + clk_621);
-	clks[cpu_2x_clk].name = "cpu_2x";
 
 	clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
 	clks[cpu_1x_clk].parent = cpu_6or4x_clk;
 	clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
 			(4 + 2 * clk_621);
-	clks[cpu_1x_clk].name = "cpu_1x";
 }
 
 /**
@@ -338,13 +343,11 @@ static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
  * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
  * @clk:	Pointer to struct clk for the clock
  * @ctrl:	Clock control register
- * @name:	PLL name
  * @two_divs:	Indicates whether the clock features one or two dividers
  */
-static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
+static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl,
 		bool two_divs)
 {
-	clk->name = name;
 	clk->reg = ctrl;
 	if (two_divs)
 		clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
@@ -358,59 +361,57 @@ static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl, char *name,
 
 static void init_periph_clocks(void)
 {
-	zynq_clk_register_periph_clk(&clks[gem0_clk], &slcr_base->gem0_clk_ctrl,
-				     "gem0", 1);
-	zynq_clk_register_periph_clk(&clks[gem1_clk], &slcr_base->gem1_clk_ctrl,
-				     "gem1", 1);
+	zynq_clk_register_periph_clk(&clks[gem0_clk],
+				     &slcr_base->gem0_clk_ctrl, 1);
+	zynq_clk_register_periph_clk(&clks[gem1_clk],
+				     &slcr_base->gem1_clk_ctrl, 1);
 
-	zynq_clk_register_periph_clk(&clks[smc_clk], &slcr_base->smc_clk_ctrl,
-				     "smc", 0);
+	zynq_clk_register_periph_clk(&clks[smc_clk],
+				     &slcr_base->smc_clk_ctrl, 0);
 
 	zynq_clk_register_periph_clk(&clks[lqspi_clk],
-				     &slcr_base->lqspi_clk_ctrl, "lqspi", 0);
+				     &slcr_base->lqspi_clk_ctrl, 0);
 
 	zynq_clk_register_periph_clk(&clks[sdio0_clk],
-				     &slcr_base->sdio_clk_ctrl, "sdio0", 0);
+				     &slcr_base->sdio_clk_ctrl, 0);
 	zynq_clk_register_periph_clk(&clks[sdio1_clk],
-				     &slcr_base->sdio_clk_ctrl, "sdio1", 0);
+				     &slcr_base->sdio_clk_ctrl, 0);
 
-	zynq_clk_register_periph_clk(&clks[spi0_clk], &slcr_base->spi_clk_ctrl,
-				     "spi0", 0);
-	zynq_clk_register_periph_clk(&clks[spi1_clk], &slcr_base->spi_clk_ctrl,
-				     "spi1", 0);
+	zynq_clk_register_periph_clk(&clks[spi0_clk],
+				     &slcr_base->spi_clk_ctrl, 0);
+	zynq_clk_register_periph_clk(&clks[spi1_clk],
+				     &slcr_base->spi_clk_ctrl, 0);
 
 	zynq_clk_register_periph_clk(&clks[uart0_clk],
-				     &slcr_base->uart_clk_ctrl, "uart0", 0);
+				     &slcr_base->uart_clk_ctrl, 0);
 	zynq_clk_register_periph_clk(&clks[uart1_clk],
-				     &slcr_base->uart_clk_ctrl, "uart1", 0);
+				     &slcr_base->uart_clk_ctrl, 0);
 
 	zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
-				     &slcr_base->dbg_clk_ctrl, "dbg_trc", 0);
+				     &slcr_base->dbg_clk_ctrl, 0);
 	zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
-				     &slcr_base->dbg_clk_ctrl, "dbg_apb", 0);
+				     &slcr_base->dbg_clk_ctrl, 0);
 
 	zynq_clk_register_periph_clk(&clks[pcap_clk],
-				     &slcr_base->pcap_clk_ctrl, "pcap", 0);
+				     &slcr_base->pcap_clk_ctrl, 0);
 
 	zynq_clk_register_periph_clk(&clks[fclk0_clk],
-				     &slcr_base->fpga0_clk_ctrl, "fclk0", 1);
+				     &slcr_base->fpga0_clk_ctrl, 1);
 	zynq_clk_register_periph_clk(&clks[fclk1_clk],
-				     &slcr_base->fpga1_clk_ctrl, "fclk1", 1);
+				     &slcr_base->fpga1_clk_ctrl, 1);
 	zynq_clk_register_periph_clk(&clks[fclk2_clk],
-				     &slcr_base->fpga2_clk_ctrl, "fclk2", 1);
+				     &slcr_base->fpga2_clk_ctrl, 1);
 	zynq_clk_register_periph_clk(&clks[fclk3_clk],
-				     &slcr_base->fpga3_clk_ctrl, "fclk3", 1);
+				     &slcr_base->fpga3_clk_ctrl, 1);
 }
 
 /**
  * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
  * @clk:	Pointer to struct clk for the clock
  * @ctrl:	Clock control register
- * @name:	PLL name
  */
-static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
+static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl)
 {
-	clk->name = name;
 	clk->reg = ctrl;
 	clk->parent = cpu_1x_clk;
 	clk->frequency = zynq_clk_get_rate(clk->parent);
@@ -419,48 +420,48 @@ static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl, char *name)
 static void init_aper_clocks(void)
 {
 	zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "usb0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "usb1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "gem0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "gem1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "sdio0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "sdio1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "spi0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "spi1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[can0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "can0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[can1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "can1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "i2c0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "i2c1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "uart0_aper");
+				   &slcr_base->aper_clk_ctrl);
 	zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "uart1_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "gpio_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "lqspi_aper");
+				   &slcr_base->aper_clk_ctrl);
 
 	zynq_clk_register_aper_clk(&clks[smc_aper_clk],
-				   &slcr_base->aper_clk_ctrl, "smc_aper");
+				   &slcr_base->aper_clk_ctrl);
 }
 
 /**
@@ -496,13 +497,11 @@ static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
  * zynq_clk_register_pll() - Set up a PLL with the framework
  * @clk:	Pointer to struct clk for the PLL
  * @ctrl:	PLL control register
- * @name:	PLL name
  * @prate:	PLL input clock rate
  */
-static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl, char *name,
+static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl,
 		unsigned long prate)
 {
-	clk->name = name;
 	clk->reg = ctrl;
 	clk->frequency = zynq_clk_pll_get_rate(clk);
 	clk->ops.get_rate = zynq_clk_pll_get_rate;
@@ -583,11 +582,11 @@ unsigned long get_uart_clk(int dev_index)
 int set_cpu_clk_info(void)
 {
 	zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
-			      "armpll", CONFIG_ZYNQ_PS_CLK_FREQ);
+			      CONFIG_ZYNQ_PS_CLK_FREQ);
 	zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
-			      "ddrpll", CONFIG_ZYNQ_PS_CLK_FREQ);
+			      CONFIG_ZYNQ_PS_CLK_FREQ);
 	zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
-			      "iopll", CONFIG_ZYNQ_PS_CLK_FREQ);
+			      CONFIG_ZYNQ_PS_CLK_FREQ);
 
 	init_ddr_clocks();
 	init_cpu_clocks();
@@ -639,7 +638,7 @@ int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
  */
 const char *zynq_clk_get_name(enum zynq_clk clk)
 {
-	return clks[clk].name;
+	return clk_names[clk];
 }
 
 /**
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 05/10] zynq: Remove zynq_clk_get_name function
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (3 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 04/10] zynq: Move static clock names into separate array stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 06/10] clk: zynq: Add zynq clock framework driver stefan.herbrechtsmeier at weidmueller.com
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

The zynq_clk_get_name function is only used once inside the clock
driver. Replace the function call with the one-line code.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
Reviewed-by: Michal Simek <michal.simek@xilinx.com>
---

Changes in v2: None

 arch/arm/mach-zynq/clk.c              | 12 +-----------
 arch/arm/mach-zynq/include/mach/clk.h |  1 -
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index 7bff964..570ebd7 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -632,16 +632,6 @@ int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
 }
 
 /**
- * zynq_clk_get_name() - Get clock name
- * @clk:	Clock identifier
- * Returns the name of @clk.
- */
-const char *zynq_clk_get_name(enum zynq_clk clk)
-{
-	return clk_names[clk];
-}
-
-/**
  * soc_clk_dump() - Print clock frequencies
  * Returns zero on success
  *
@@ -653,7 +643,7 @@ int soc_clk_dump(void)
 
 	printf("clk\t\tfrequency\n");
 	for (i = 0; i < clk_max; i++) {
-		const char *name = zynq_clk_get_name(i);
+		const char *name = clk_names[i];
 		if (name)
 			printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
 	}
diff --git a/arch/arm/mach-zynq/include/mach/clk.h b/arch/arm/mach-zynq/include/mach/clk.h
index 250c5bc..5c2758a 100644
--- a/arch/arm/mach-zynq/include/mach/clk.h
+++ b/arch/arm/mach-zynq/include/mach/clk.h
@@ -23,7 +23,6 @@ enum zynq_clk {
 void zynq_clk_early_init(void);
 int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate);
 unsigned long zynq_clk_get_rate(enum zynq_clk clk);
-const char *zynq_clk_get_name(enum zynq_clk clk);
 unsigned long get_uart_clk(int dev_id);
 
 #endif
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 06/10] clk: zynq: Add zynq clock framework driver
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (4 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 05/10] zynq: Remove zynq_clk_get_name function stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 07/10] zynq: Move zynq to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Add a clock framework driver for the zynq platform. The driver is based
on the platform zynq clock driver but reworked to use static functions
instead of run-time generated objects even for unused clocks.
Additionally the CONFIG_ZYNQ_PS_CLK_FREQ is replaced by the
ps-clk-frequency from the device tree.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

---

Changes in v2:
- Group ifndef CONFIG_SPL_BUILD inside switch case of zynq_clk_get_register()
- Put same switch case code together in zynq_clk_get_*_pll()
- Replace ZYNQ_CLKMUX_SEL_* by there numbers
- Return error code and add debug message for unknown gem eimo rx clock source
- Correct zynq_clk_calc_peripheral_two_divs() parameter indetation

 drivers/clk/Kconfig    |   8 +
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk_zynq.c | 459 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 468 insertions(+)
 create mode 100644 drivers/clk/clk_zynq.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 335ef9e..5ca958c 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -28,6 +28,14 @@ config CLK_BOSTON
 	help
 	  Enable this to support the clocks
 
+config CLK_ZYNQ
+	bool "Enable clock driver support for Zynq"
+	depends on CLK && ARCH_ZYNQ
+	default y
+	help
+	  This clock driver adds support for clock realted settings for
+	  Zynq platform.
+
 config CLK_ZYNQMP
 	bool "Enable clock driver support for ZynqMP"
 	depends on ARCH_ZYNQMP
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f55348e..ce9df25 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
 obj-$(CONFIG_CLK_AT91) += at91/
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
new file mode 100644
index 0000000..a070f01
--- /dev/null
+++ b/drivers/clk/clk_zynq.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2017 Weidm?ller Interface GmbH & Co. KG
+ * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
+ *
+ * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com>
+ * Copyright (C) 2013 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+/* Register bitfield defines */
+#define PLLCTRL_FBDIV_MASK	0x7f000
+#define PLLCTRL_FBDIV_SHIFT	12
+#define PLLCTRL_BPFORCE_MASK	(1 << 4)
+#define PLLCTRL_PWRDWN_MASK	2
+#define PLLCTRL_PWRDWN_SHIFT	1
+#define PLLCTRL_RESET_MASK	1
+#define PLLCTRL_RESET_SHIFT	0
+
+#define ZYNQ_CLK_MAXDIV		0x3f
+#define CLK_CTRL_DIV1_SHIFT	20
+#define CLK_CTRL_DIV1_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
+#define CLK_CTRL_DIV0_SHIFT	8
+#define CLK_CTRL_DIV0_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
+#define CLK_CTRL_SRCSEL_SHIFT	4
+#define CLK_CTRL_SRCSEL_MASK	(0x3 << CLK_CTRL_SRCSEL_SHIFT)
+
+#define CLK_CTRL_DIV2X_SHIFT	26
+#define CLK_CTRL_DIV2X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
+#define CLK_CTRL_DIV3X_SHIFT	20
+#define CLK_CTRL_DIV3X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SPL_BUILD
+enum zynq_clk_rclk {mio_clk, emio_clk};
+#endif
+
+struct zynq_clk_priv {
+	ulong ps_clk_freq;
+};
+
+static void *zynq_clk_get_register(enum zynq_clk id)
+{
+	switch (id) {
+	case armpll_clk:
+		return &slcr_base->arm_pll_ctrl;
+	case ddrpll_clk:
+		return &slcr_base->ddr_pll_ctrl;
+	case iopll_clk:
+		return &slcr_base->io_pll_ctrl;
+	case lqspi_clk:
+		return &slcr_base->lqspi_clk_ctrl;
+	case smc_clk:
+		return &slcr_base->smc_clk_ctrl;
+	case pcap_clk:
+		return &slcr_base->pcap_clk_ctrl;
+	case sdio0_clk ... sdio1_clk:
+		return &slcr_base->sdio_clk_ctrl;
+	case uart0_clk ... uart1_clk:
+		return &slcr_base->uart_clk_ctrl;
+	case spi0_clk ... spi1_clk:
+		return &slcr_base->spi_clk_ctrl;
+#ifndef CONFIG_SPL_BUILD
+	case dci_clk:
+		return &slcr_base->dci_clk_ctrl;
+	case gem0_clk:
+		return &slcr_base->gem0_clk_ctrl;
+	case gem1_clk:
+		return &slcr_base->gem1_clk_ctrl;
+	case fclk0_clk:
+		return &slcr_base->fpga0_clk_ctrl;
+	case fclk1_clk:
+		return &slcr_base->fpga1_clk_ctrl;
+	case fclk2_clk:
+		return &slcr_base->fpga2_clk_ctrl;
+	case fclk3_clk:
+		return &slcr_base->fpga3_clk_ctrl;
+	case can0_clk ... can1_clk:
+		return &slcr_base->can_clk_ctrl;
+	case dbg_trc_clk ... dbg_apb_clk:
+		/* fall through */
+#endif
+	default:
+		return &slcr_base->dbg_clk_ctrl;
+	}
+}
+
+static enum zynq_clk zynq_clk_get_cpu_pll(u32 clk_ctrl)
+{
+	u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+
+	switch (srcsel) {
+	case 2:
+		return ddrpll_clk;
+	case 3:
+		return iopll_clk;
+	case 0 ... 1:
+	default:
+		return armpll_clk;
+	}
+}
+
+static enum zynq_clk zynq_clk_get_peripheral_pll(u32 clk_ctrl)
+{
+	u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+
+	switch (srcsel) {
+	case 2:
+		return armpll_clk;
+	case 3:
+		return ddrpll_clk;
+	case 0 ... 1:
+	default:
+		return iopll_clk;
+	}
+}
+
+static ulong zynq_clk_get_pll_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
+{
+	u32 clk_ctrl, reset, pwrdwn, mul, bypass;
+
+	clk_ctrl = readl(zynq_clk_get_register(id));
+
+	reset = (clk_ctrl & PLLCTRL_RESET_MASK) >> PLLCTRL_RESET_SHIFT;
+	pwrdwn = (clk_ctrl & PLLCTRL_PWRDWN_MASK) >> PLLCTRL_PWRDWN_SHIFT;
+	if (reset || pwrdwn)
+		return 0;
+
+	bypass = clk_ctrl & PLLCTRL_BPFORCE_MASK;
+	if (bypass)
+		mul = 1;
+	else
+		mul = (clk_ctrl & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
+
+	return priv->ps_clk_freq * mul;
+}
+
+#ifndef CONFIG_SPL_BUILD
+static enum zynq_clk_rclk zynq_clk_get_gem_rclk(enum zynq_clk id)
+{
+	u32 clk_ctrl, srcsel;
+
+	if (id == gem0_clk)
+		clk_ctrl = readl(&slcr_base->gem0_rclk_ctrl);
+	else
+		clk_ctrl = readl(&slcr_base->gem1_rclk_ctrl);
+
+	srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
+	if (srcsel)
+		return emio_clk;
+	else
+		return mio_clk;
+}
+#endif
+
+static ulong zynq_clk_get_cpu_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
+{
+	u32 clk_621, clk_ctrl, div;
+	enum zynq_clk pll;
+
+	clk_ctrl = readl(&slcr_base->arm_clk_ctrl);
+
+	div = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+
+	switch (id) {
+	case cpu_1x_clk:
+		div *= 2;
+		/* fall through */
+	case cpu_2x_clk:
+		clk_621 = readl(&slcr_base->clk_621_true) & 1;
+		div *= 2 + clk_621;
+		break;
+	case cpu_3or2x_clk:
+		div *= 2;
+		/* fall through */
+	case cpu_6or4x_clk:
+		break;
+	default:
+		return 0;
+	}
+
+	pll = zynq_clk_get_cpu_pll(clk_ctrl);
+
+	return DIV_ROUND_CLOSEST(zynq_clk_get_pll_rate(priv, pll), div);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_ddr2x_rate(struct zynq_clk_priv *priv)
+{
+	u32 clk_ctrl, div;
+
+	clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
+
+	div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
+
+	return DIV_ROUND_CLOSEST(zynq_clk_get_pll_rate(priv, ddrpll_clk), div);
+}
+#endif
+
+static ulong zynq_clk_get_ddr3x_rate(struct zynq_clk_priv *priv)
+{
+	u32 clk_ctrl, div;
+
+	clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
+
+	div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
+
+	return DIV_ROUND_CLOSEST(zynq_clk_get_pll_rate(priv, ddrpll_clk), div);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_dci_rate(struct zynq_clk_priv *priv)
+{
+	u32 clk_ctrl, div0, div1;
+
+	clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
+
+	div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+	div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
+
+	return DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(
+		zynq_clk_get_pll_rate(priv, ddrpll_clk), div0), div1);
+}
+#endif
+
+static ulong zynq_clk_get_peripheral_rate(struct zynq_clk_priv *priv,
+					  enum zynq_clk id, bool two_divs)
+{
+	enum zynq_clk pll;
+	u32 clk_ctrl, div0;
+	u32 div1 = 1;
+
+	clk_ctrl = readl(zynq_clk_get_register(id));
+
+	div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+	if (!div0)
+		div0 = 1;
+
+#ifndef CONFIG_SPL_BUILD
+	if (two_divs) {
+		div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
+		if (!div1)
+			div1 = 1;
+	}
+#endif
+
+	pll = zynq_clk_get_peripheral_pll(clk_ctrl);
+
+	return
+		DIV_ROUND_CLOSEST(
+			DIV_ROUND_CLOSEST(
+				zynq_clk_get_pll_rate(priv, pll), div0),
+			div1);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_gem_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
+{
+	if (zynq_clk_get_gem_rclk(id) == mio_clk)
+		return zynq_clk_get_peripheral_rate(priv, id, true);
+
+	debug("%s: gem%d emio rx clock source unknown\n", __func__,
+	      id - gem0_clk);
+
+	return -ENOSYS;
+}
+
+static unsigned long zynq_clk_calc_peripheral_two_divs(ulong rate,
+						       ulong pll_rate,
+						       u32 *div0, u32 *div1)
+{
+	long new_err, best_err = (long)(~0UL >> 1);
+	ulong new_rate, best_rate = 0;
+	u32 d0, d1;
+
+	for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
+		for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
+			new_rate = DIV_ROUND_CLOSEST(
+					DIV_ROUND_CLOSEST(pll_rate, d0), d1);
+			new_err = abs(new_rate - rate);
+
+			if (new_err < best_err) {
+				*div0 = d0;
+				*div1 = d1;
+				best_err = new_err;
+				best_rate = new_rate;
+			}
+		}
+	}
+
+	return best_rate;
+}
+
+static ulong zynq_clk_set_peripheral_rate(struct zynq_clk_priv *priv,
+					  enum zynq_clk id, ulong rate,
+					  bool two_divs)
+{
+	enum zynq_clk pll;
+	u32 clk_ctrl, div0 = 0, div1 = 0;
+	ulong pll_rate, new_rate;
+	u32 *reg;
+
+	reg = zynq_clk_get_register(id);
+	clk_ctrl = readl(reg);
+
+	pll = zynq_clk_get_peripheral_pll(clk_ctrl);
+	pll_rate = zynq_clk_get_pll_rate(priv, pll);
+	clk_ctrl &= ~CLK_CTRL_DIV0_MASK;
+	if (two_divs) {
+		clk_ctrl &= ~CLK_CTRL_DIV1_MASK;
+		new_rate = zynq_clk_calc_peripheral_two_divs(rate, pll_rate,
+				&div0, &div1);
+		clk_ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
+	} else {
+		div0 = DIV_ROUND_CLOSEST(pll_rate, rate);
+		if (div0 > ZYNQ_CLK_MAXDIV)
+			div0 = ZYNQ_CLK_MAXDIV;
+		new_rate = DIV_ROUND_CLOSEST(rate, div0);
+	}
+	clk_ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
+
+	zynq_slcr_unlock();
+	writel(clk_ctrl, reg);
+	zynq_slcr_lock();
+
+	return new_rate;
+}
+
+static ulong zynq_clk_set_gem_rate(struct zynq_clk_priv *priv, enum zynq_clk id,
+				   ulong rate)
+{
+	if (zynq_clk_get_gem_rclk(id) == mio_clk)
+		return zynq_clk_set_peripheral_rate(priv, id, rate, true);
+
+	debug("%s: gem%d emio rx clock source unknown\n", __func__,
+	      id - gem0_clk);
+
+	return -ENOSYS;
+}
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+static ulong zynq_clk_get_rate(struct clk *clk)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(clk->dev);
+	enum zynq_clk id = clk->id;
+	bool two_divs = false;
+
+	switch (id) {
+	case armpll_clk ... iopll_clk:
+		return zynq_clk_get_pll_rate(priv, id);
+	case cpu_6or4x_clk ... cpu_1x_clk:
+		return zynq_clk_get_cpu_rate(priv, id);
+	case ddr2x_clk:
+		return zynq_clk_get_ddr2x_rate(priv);
+	case ddr3x_clk:
+		return zynq_clk_get_ddr3x_rate(priv);
+	case dci_clk:
+		return zynq_clk_get_dci_rate(priv);
+	case gem0_clk ... gem1_clk:
+		return zynq_clk_get_gem_rate(priv, id);
+	case fclk0_clk ... can1_clk:
+		two_divs = true;
+		/* fall through */
+	case dbg_trc_clk ... dbg_apb_clk:
+	case lqspi_clk ... pcap_clk:
+	case sdio0_clk ... spi1_clk:
+		return zynq_clk_get_peripheral_rate(priv, id, two_divs);
+	case dma_clk:
+		return zynq_clk_get_cpu_rate(priv, cpu_2x_clk);
+	case usb0_aper_clk ... smc_aper_clk:
+		return zynq_clk_get_cpu_rate(priv, cpu_1x_clk);
+	default:
+		return -ENXIO;
+	}
+}
+
+static ulong zynq_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(clk->dev);
+	enum zynq_clk id = clk->id;
+	bool two_divs = false;
+
+	switch (id) {
+	case gem0_clk ... gem1_clk:
+		return zynq_clk_set_gem_rate(priv, id, rate);
+	case fclk0_clk ... can1_clk:
+		two_divs = true;
+		/* fall through */
+	case lqspi_clk ... pcap_clk:
+	case sdio0_clk ... spi1_clk:
+	case dbg_trc_clk ... dbg_apb_clk:
+		return zynq_clk_set_peripheral_rate(priv, id, rate, two_divs);
+	default:
+		return -ENXIO;
+	}
+}
+#else
+static ulong zynq_clk_get_rate(struct clk *clk)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(clk->dev);
+	enum zynq_clk id = clk->id;
+
+	switch (id) {
+	case cpu_6or4x_clk ... cpu_1x_clk:
+		return zynq_clk_get_cpu_rate(priv, id);
+	case ddr3x_clk:
+		return zynq_clk_get_ddr3x_rate(priv);
+	case lqspi_clk ... pcap_clk:
+	case sdio0_clk ... spi1_clk:
+		return zynq_clk_get_peripheral_rate(priv, id, 0);
+	default:
+		return -ENXIO;
+	}
+}
+#endif
+
+static struct clk_ops zynq_clk_ops = {
+	.get_rate = zynq_clk_get_rate,
+#ifndef CONFIG_SPL_BUILD
+	.set_rate = zynq_clk_set_rate,
+#endif
+};
+
+static int zynq_clk_probe(struct udevice *dev)
+{
+	struct zynq_clk_priv *priv = dev_get_priv(dev);
+
+	priv->ps_clk_freq = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
+					    "ps-clk-frequency", 33333333UL);
+
+	return 0;
+}
+
+static const struct udevice_id zynq_clk_ids[] = {
+	{ .compatible = "xlnx,ps7-clkc"},
+	{}
+};
+
+U_BOOT_DRIVER(zynq_clk) = {
+	.name		= "zynq_clk",
+	.id		= UCLASS_CLK,
+	.of_match	= zynq_clk_ids,
+	.flags		= DM_FLAG_PRE_RELOC,
+	.ops		= &zynq_clk_ops,
+	.priv_auto_alloc_size = sizeof(struct zynq_clk_priv),
+	.probe		= zynq_clk_probe,
+};
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 07/10] zynq: Move zynq to clock framework
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (5 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 06/10] clk: zynq: Add zynq clock framework driver stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 08/10] clk: zynq: Add optional ethernet emio clock source support stefan.herbrechtsmeier at weidmueller.com
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Move the zynq to clock framework and remove unused functions as well as
the CONFIG_ZYNQ_PS_CLK_FREQ configuration.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

---

Changes in v2:
- Add support for unknown clock rate to soc_clk_dump()

 arch/arm/Kconfig                            |   3 +
 arch/arm/dts/zynq-7000.dtsi                 |   2 +
 arch/arm/mach-zynq/clk.c                    | 653 +++-------------------------
 arch/arm/mach-zynq/cpu.c                    |   1 -
 arch/arm/mach-zynq/include/mach/clk.h       |   5 -
 arch/arm/mach-zynq/include/mach/sys_proto.h |   1 -
 arch/arm/mach-zynq/slcr.c                   |  22 -
 arch/arm/mach-zynq/timer.c                  |   2 -
 drivers/net/zynq_gem.c                      |   9 -
 drivers/serial/serial_zynq.c                |   6 +-
 include/configs/topic_miami.h               |   2 -
 include/configs/zynq_zybo.h                 |   3 -
 scripts/config_whitelist.txt                |   1 -
 13 files changed, 59 insertions(+), 651 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0ed36cd..449f4af 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -647,6 +647,9 @@ config ARCH_ZYNQ
 	select SPL_SEPARATE_BSS if SPL
 	select DM_USB if USB
 	select BLK
+	select CLK
+	select SPL_CLK
+	select CLK_ZYNQ
 
 config ARCH_ZYNQMP
 	bool "Support Xilinx ZynqMP Platform"
diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi
index fa9ee27..34fc6e5 100644
--- a/arch/arm/dts/zynq-7000.dtsi
+++ b/arch/arm/dts/zynq-7000.dtsi
@@ -248,12 +248,14 @@
 		};
 
 		slcr: slcr at f8000000 {
+			u-boot,dm-pre-reloc;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd";
 			reg = <0xF8000000 0x1000>;
 			ranges;
 			clkc: clkc at 100 {
+				u-boot,dm-pre-reloc;
 				#clock-cells = <1>;
 				compatible = "xlnx,ps7-clkc";
 				fclk-enable = <0>;
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index 570ebd7..1369cd0 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -4,77 +4,13 @@
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
+#include <clk.h>
 #include <common.h>
-#include <errno.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
+#include <dm.h>
 #include <asm/arch/clk.h>
 
-/* Board oscillator frequency */
-#ifndef CONFIG_ZYNQ_PS_CLK_FREQ
-# define CONFIG_ZYNQ_PS_CLK_FREQ	33333333UL
-#endif
-
-/* Register bitfield defines */
-#define PLLCTRL_FBDIV_MASK	0x7f000
-#define PLLCTRL_FBDIV_SHIFT	12
-#define PLLCTRL_BPFORCE_MASK	(1 << 4)
-#define PLLCTRL_PWRDWN_MASK	2
-#define PLLCTRL_PWRDWN_SHIFT	1
-#define PLLCTRL_RESET_MASK	1
-#define PLLCTRL_RESET_SHIFT	0
-
-#define ZYNQ_CLK_MAXDIV		0x3f
-#define CLK_CTRL_DIV1_SHIFT	20
-#define CLK_CTRL_DIV1_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV1_SHIFT)
-#define CLK_CTRL_DIV0_SHIFT	8
-#define CLK_CTRL_DIV0_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV0_SHIFT)
-#define CLK_CTRL_SRCSEL_SHIFT	4
-#define CLK_CTRL_SRCSEL_MASK	(0x3 << CLK_CTRL_SRCSEL_SHIFT)
-
-#define CLK_CTRL_DIV2X_SHIFT	26
-#define CLK_CTRL_DIV2X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV2X_SHIFT)
-#define CLK_CTRL_DIV3X_SHIFT	20
-#define CLK_CTRL_DIV3X_MASK	(ZYNQ_CLK_MAXDIV << CLK_CTRL_DIV3X_SHIFT)
-
-#define ZYNQ_CLKMUX_SEL_0	0
-#define ZYNQ_CLKMUX_SEL_1	1
-#define ZYNQ_CLKMUX_SEL_2	2
-#define ZYNQ_CLKMUX_SEL_3	3
-
 DECLARE_GLOBAL_DATA_PTR;
 
-struct clk;
-
-/**
- * struct zynq_clk_ops:
- * @set_rate:	Function pointer to set_rate() implementation
- * @get_rate:	Function pointer to get_rate() implementation
- */
-struct zynq_clk_ops {
-	int (*set_rate)(struct clk *clk, unsigned long rate);
-	unsigned long (*get_rate)(struct clk *clk);
-};
-
-/**
- * struct clk:
- * @frequency:	Currenct frequency
- * @parent:	Parent clock
- * @flags:	Clock flags
- * @reg:	Clock control register
- * @ops:	Clock operations
- */
-struct clk {
-	unsigned long	frequency;
-	enum zynq_clk	parent;
-	unsigned int	flags;
-	u32		*reg;
-	struct zynq_clk_ops	ops;
-};
-#define ZYNQ_CLK_FLAGS_HAS_2_DIVS	1
-
-static struct clk clks[clk_max];
-
 static const char * const clk_names[clk_max] = {
 	"armpll", "ddrpll", "iopll",
 	"cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x",
@@ -90,548 +26,43 @@ static const char * const clk_names[clk_max] = {
 };
 
 /**
- * __zynq_clk_cpu_get_parent() - Decode clock multiplexer
- * @srcsel:	Mux select value
- * Returns the clock identifier associated with the selected mux input.
- */
-static int __zynq_clk_cpu_get_parent(unsigned int srcsel)
-{
-	unsigned int ret;
-
-	switch (srcsel) {
-	case ZYNQ_CLKMUX_SEL_0:
-	case ZYNQ_CLKMUX_SEL_1:
-		ret = armpll_clk;
-		break;
-	case ZYNQ_CLKMUX_SEL_2:
-		ret = ddrpll_clk;
-		break;
-	case ZYNQ_CLKMUX_SEL_3:
-		ret = iopll_clk;
-		break;
-	default:
-		ret = armpll_clk;
-		break;
-	}
-
-	return ret;
-}
-
-/**
- * ddr2x_get_rate() - Get clock rate of DDR2x clock
- * @clk:	Clock handle
- * Returns the current clock rate of @clk.
- */
-static unsigned long ddr2x_get_rate(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 div = (clk_ctrl & CLK_CTRL_DIV2X_MASK) >> CLK_CTRL_DIV2X_SHIFT;
-
-	return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
-}
-
-/**
- * ddr3x_get_rate() - Get clock rate of DDR3x clock
- * @clk:	Clock handle
- * Returns the current clock rate of @clk.
- */
-static unsigned long ddr3x_get_rate(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 div = (clk_ctrl & CLK_CTRL_DIV3X_MASK) >> CLK_CTRL_DIV3X_SHIFT;
-
-	return DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div);
-}
-
-static void init_ddr_clocks(void)
-{
-	u32 div0, div1;
-	unsigned long prate = zynq_clk_get_rate(ddrpll_clk);
-	u32 clk_ctrl = readl(&slcr_base->ddr_clk_ctrl);
-
-	/* DDR2x */
-	clks[ddr2x_clk].reg = &slcr_base->ddr_clk_ctrl;
-	clks[ddr2x_clk].parent = ddrpll_clk;
-	clks[ddr2x_clk].frequency = ddr2x_get_rate(&clks[ddr2x_clk]);
-	clks[ddr2x_clk].ops.get_rate = ddr2x_get_rate;
-
-	/* DDR3x */
-	clks[ddr3x_clk].reg = &slcr_base->ddr_clk_ctrl;
-	clks[ddr3x_clk].parent = ddrpll_clk;
-	clks[ddr3x_clk].frequency = ddr3x_get_rate(&clks[ddr3x_clk]);
-	clks[ddr3x_clk].ops.get_rate = ddr3x_get_rate;
-
-	/* DCI */
-	clk_ctrl = readl(&slcr_base->dci_clk_ctrl);
-	div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
-	clks[dci_clk].reg = &slcr_base->dci_clk_ctrl;
-	clks[dci_clk].parent = ddrpll_clk;
-	clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
-			DIV_ROUND_CLOSEST(prate, div0), div1);
-
-	gd->bd->bi_ddr_freq = clks[ddr3x_clk].frequency / 1000000;
-}
-
-static void init_cpu_clocks(void)
-{
-	int clk_621;
-	u32 reg, div, srcsel;
-	enum zynq_clk parent;
-
-	reg = readl(&slcr_base->arm_clk_ctrl);
-	clk_621 = readl(&slcr_base->clk_621_true) & 1;
-	div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-	parent = __zynq_clk_cpu_get_parent(srcsel);
-
-	/* cpu clocks */
-	clks[cpu_6or4x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_6or4x_clk].parent = parent;
-	clks[cpu_6or4x_clk].frequency = DIV_ROUND_CLOSEST(
-			zynq_clk_get_rate(parent), div);
-
-	clks[cpu_3or2x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_3or2x_clk].parent = cpu_6or4x_clk;
-	clks[cpu_3or2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) / 2;
-
-	clks[cpu_2x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_2x_clk].parent = cpu_6or4x_clk;
-	clks[cpu_2x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
-			(2 + clk_621);
-
-	clks[cpu_1x_clk].reg = &slcr_base->arm_clk_ctrl;
-	clks[cpu_1x_clk].parent = cpu_6or4x_clk;
-	clks[cpu_1x_clk].frequency = zynq_clk_get_rate(cpu_6or4x_clk) /
-			(4 + 2 * clk_621);
-}
-
-/**
- * periph_calc_two_divs() - Calculate clock dividers
- * @cur_rate:	Current clock rate
- * @tgt_rate:	Target clock rate
- * @prate:	Parent clock rate
- * @div0:	First divider (output)
- * @div1:	Second divider (output)
- * Returns the actual clock rate possible.
- *
- * Calculates clock dividers for clocks with two 6-bit dividers.
- */
-static unsigned long periph_calc_two_divs(unsigned long cur_rate,
-		unsigned long tgt_rate, unsigned long prate, u32 *div0,
-		u32 *div1)
-{
-	long err, best_err = (long)(~0UL >> 1);
-	unsigned long rate, best_rate = 0;
-	u32 d0, d1;
-
-	for (d0 = 1; d0 <= ZYNQ_CLK_MAXDIV; d0++) {
-		for (d1 = 1; d1 <= ZYNQ_CLK_MAXDIV >> 1; d1++) {
-			rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(prate, d0),
-					d1);
-			err = abs(rate - tgt_rate);
-
-			if (err < best_err) {
-				*div0 = d0;
-				*div1 = d1;
-				best_err = err;
-				best_rate = rate;
-			}
-		}
-	}
-
-	return best_rate;
-}
-
-/**
- * zynq_clk_periph_set_rate() - Set clock rate
- * @clk:	Handle of the peripheral clock
- * @rate:	New clock rate
- * Sets the clock frequency of @clk to @rate. Returns zero on success.
- */
-static int zynq_clk_periph_set_rate(struct clk *clk,
-		unsigned long rate)
-{
-	u32 ctrl, div0 = 0, div1 = 0;
-	unsigned long prate, new_rate, cur_rate = clk->frequency;
-
-	ctrl = readl(clk->reg);
-	prate = zynq_clk_get_rate(clk->parent);
-	ctrl &= ~CLK_CTRL_DIV0_MASK;
-
-	if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS) {
-		ctrl &= ~CLK_CTRL_DIV1_MASK;
-		new_rate = periph_calc_two_divs(cur_rate, rate, prate, &div0,
-				&div1);
-		ctrl |= div1 << CLK_CTRL_DIV1_SHIFT;
-	} else {
-		div0 = DIV_ROUND_CLOSEST(prate, rate);
-		div0 &= ZYNQ_CLK_MAXDIV;
-		new_rate = DIV_ROUND_CLOSEST(rate, div0);
-	}
-
-	/* write new divs to hardware */
-	ctrl |= div0 << CLK_CTRL_DIV0_SHIFT;
-	writel(ctrl, clk->reg);
-
-	/* update frequency in clk framework */
-	clk->frequency = new_rate;
-
-	return 0;
-}
-
-/**
- * zynq_clk_periph_get_rate() - Get clock rate
- * @clk:	Handle of the peripheral clock
- * Returns the current clock rate of @clk.
- */
-static unsigned long zynq_clk_periph_get_rate(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	u32 div1 = 1;
-
-	if (clk->flags & ZYNQ_CLK_FLAGS_HAS_2_DIVS)
-		div1 = (clk_ctrl & CLK_CTRL_DIV1_MASK) >> CLK_CTRL_DIV1_SHIFT;
-
-	/* a register value of zero == division by 1 */
-	if (!div0)
-		div0 = 1;
-	if (!div1)
-		div1 = 1;
-
-	return
-		DIV_ROUND_CLOSEST(
-			DIV_ROUND_CLOSEST(zynq_clk_get_rate(clk->parent), div0),
-			div1);
-}
-
-/**
- * __zynq_clk_periph_get_parent() - Decode clock multiplexer
- * @srcsel:	Mux select value
- * Returns the clock identifier associated with the selected mux input.
- */
-static enum zynq_clk __zynq_clk_periph_get_parent(u32 srcsel)
-{
-	switch (srcsel) {
-	case ZYNQ_CLKMUX_SEL_0:
-	case ZYNQ_CLKMUX_SEL_1:
-		return iopll_clk;
-	case ZYNQ_CLKMUX_SEL_2:
-		return armpll_clk;
-	case ZYNQ_CLKMUX_SEL_3:
-		return ddrpll_clk;
-	default:
-		return 0;
-	}
-}
-
-/**
- * zynq_clk_periph_get_parent() - Decode clock multiplexer
- * @clk:	Clock handle
- * Returns the clock identifier associated with the selected mux input.
- */
-static enum zynq_clk zynq_clk_periph_get_parent(struct clk *clk)
-{
-	u32 clk_ctrl = readl(clk->reg);
-	u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-
-	return __zynq_clk_periph_get_parent(srcsel);
-}
-
-/**
- * zynq_clk_register_periph_clk() - Set up a peripheral clock with the framework
- * @clk:	Pointer to struct clk for the clock
- * @ctrl:	Clock control register
- * @two_divs:	Indicates whether the clock features one or two dividers
- */
-static int zynq_clk_register_periph_clk(struct clk *clk, u32 *ctrl,
-		bool two_divs)
-{
-	clk->reg = ctrl;
-	if (two_divs)
-		clk->flags = ZYNQ_CLK_FLAGS_HAS_2_DIVS;
-	clk->parent = zynq_clk_periph_get_parent(clk);
-	clk->frequency = zynq_clk_periph_get_rate(clk);
-	clk->ops.get_rate = zynq_clk_periph_get_rate;
-	clk->ops.set_rate = zynq_clk_periph_set_rate;
-
-	return 0;
-}
-
-static void init_periph_clocks(void)
-{
-	zynq_clk_register_periph_clk(&clks[gem0_clk],
-				     &slcr_base->gem0_clk_ctrl, 1);
-	zynq_clk_register_periph_clk(&clks[gem1_clk],
-				     &slcr_base->gem1_clk_ctrl, 1);
-
-	zynq_clk_register_periph_clk(&clks[smc_clk],
-				     &slcr_base->smc_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[lqspi_clk],
-				     &slcr_base->lqspi_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[sdio0_clk],
-				     &slcr_base->sdio_clk_ctrl, 0);
-	zynq_clk_register_periph_clk(&clks[sdio1_clk],
-				     &slcr_base->sdio_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[spi0_clk],
-				     &slcr_base->spi_clk_ctrl, 0);
-	zynq_clk_register_periph_clk(&clks[spi1_clk],
-				     &slcr_base->spi_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[uart0_clk],
-				     &slcr_base->uart_clk_ctrl, 0);
-	zynq_clk_register_periph_clk(&clks[uart1_clk],
-				     &slcr_base->uart_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[dbg_trc_clk],
-				     &slcr_base->dbg_clk_ctrl, 0);
-	zynq_clk_register_periph_clk(&clks[dbg_apb_clk],
-				     &slcr_base->dbg_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[pcap_clk],
-				     &slcr_base->pcap_clk_ctrl, 0);
-
-	zynq_clk_register_periph_clk(&clks[fclk0_clk],
-				     &slcr_base->fpga0_clk_ctrl, 1);
-	zynq_clk_register_periph_clk(&clks[fclk1_clk],
-				     &slcr_base->fpga1_clk_ctrl, 1);
-	zynq_clk_register_periph_clk(&clks[fclk2_clk],
-				     &slcr_base->fpga2_clk_ctrl, 1);
-	zynq_clk_register_periph_clk(&clks[fclk3_clk],
-				     &slcr_base->fpga3_clk_ctrl, 1);
-}
-
-/**
- * zynq_clk_register_aper_clk() - Set up a APER clock with the framework
- * @clk:	Pointer to struct clk for the clock
- * @ctrl:	Clock control register
- */
-static void zynq_clk_register_aper_clk(struct clk *clk, u32 *ctrl)
-{
-	clk->reg = ctrl;
-	clk->parent = cpu_1x_clk;
-	clk->frequency = zynq_clk_get_rate(clk->parent);
-}
-
-static void init_aper_clocks(void)
-{
-	zynq_clk_register_aper_clk(&clks[usb0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[usb1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[gem0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[gem1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[sdio0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[sdio1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[spi0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[spi1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[can0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[can1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[i2c0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[i2c1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[uart0_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-	zynq_clk_register_aper_clk(&clks[uart1_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[gpio_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[lqspi_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-
-	zynq_clk_register_aper_clk(&clks[smc_aper_clk],
-				   &slcr_base->aper_clk_ctrl);
-}
-
-/**
- * __zynq_clk_pll_get_rate() - Get PLL rate
- * @addr:	Address of the PLL's control register
- * Returns the current PLL output rate.
- */
-static unsigned long __zynq_clk_pll_get_rate(u32 *addr)
-{
-	u32 reg, mul, bypass;
-
-	reg = readl(addr);
-	bypass = reg & PLLCTRL_BPFORCE_MASK;
-	if (bypass)
-		mul = 1;
-	else
-		mul = (reg & PLLCTRL_FBDIV_MASK) >> PLLCTRL_FBDIV_SHIFT;
-
-	return CONFIG_ZYNQ_PS_CLK_FREQ * mul;
-}
-
-/**
- * zynq_clk_pll_get_rate() - Get PLL rate
- * @pll:	Handle of the PLL
- * Returns the current clock rate of @pll.
- */
-static unsigned long zynq_clk_pll_get_rate(struct clk *pll)
-{
-	return __zynq_clk_pll_get_rate(pll->reg);
-}
-
-/**
- * zynq_clk_register_pll() - Set up a PLL with the framework
- * @clk:	Pointer to struct clk for the PLL
- * @ctrl:	PLL control register
- * @prate:	PLL input clock rate
- */
-static void zynq_clk_register_pll(struct clk *clk, u32 *ctrl,
-		unsigned long prate)
-{
-	clk->reg = ctrl;
-	clk->frequency = zynq_clk_pll_get_rate(clk);
-	clk->ops.get_rate = zynq_clk_pll_get_rate;
-}
-
-/**
- * clkid_2_register() - Get clock control register
- * @id:	Clock identifier of one of the PLLs
- * Returns the address of the requested PLL's control register.
- */
-static u32 *clkid_2_register(enum zynq_clk id)
-{
-	switch (id) {
-	case armpll_clk:
-		return &slcr_base->arm_pll_ctrl;
-	case ddrpll_clk:
-		return &slcr_base->ddr_pll_ctrl;
-	case iopll_clk:
-		return &slcr_base->io_pll_ctrl;
-	default:
-		return &slcr_base->io_pll_ctrl;
-	}
-}
-
-/* API */
-/**
- * zynq_clk_early_init() - Early init for the clock framework
- *
- * This function is called from before relocation and sets up the CPU clock
- * frequency in the global data struct.
- */
-void zynq_clk_early_init(void)
-{
-	u32 reg = readl(&slcr_base->arm_clk_ctrl);
-	u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-	enum zynq_clk parent = __zynq_clk_cpu_get_parent(srcsel);
-	u32 *pllreg = clkid_2_register(parent);
-	unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
-
-	if (!div)
-		div = 1;
-
-	gd->cpu_clk = DIV_ROUND_CLOSEST(prate, div);
-}
-
-/**
- * get_uart_clk() - Get UART input frequency
- * @dev_index:	UART ID
- * Returns UART input clock frequency in Hz.
- *
- * Compared to zynq_clk_get_rate() this function is designed to work before
- * relocation and can be called when the serial UART is set up.
- */
-unsigned long get_uart_clk(int dev_index)
-{
-	u32 reg = readl(&slcr_base->uart_clk_ctrl);
-	u32 div = (reg & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
-	u32 srcsel = (reg & CLK_CTRL_SRCSEL_MASK) >> CLK_CTRL_SRCSEL_SHIFT;
-	enum zynq_clk parent = __zynq_clk_periph_get_parent(srcsel);
-	u32 *pllreg = clkid_2_register(parent);
-	unsigned long prate = __zynq_clk_pll_get_rate(pllreg);
-
-	if (!div)
-		div = 1;
-
-	return DIV_ROUND_CLOSEST(prate, div);
-}
-
-/**
- * set_cpu_clk_info() - Initialize clock framework
- * Always returns zero.
+ * set_cpu_clk_info() - Setup clock information
  *
  * This function is called from common code after relocation and sets up the
- * clock framework. The framework must not be used before this function had been
- * called.
+ * clock information.
  */
 int set_cpu_clk_info(void)
 {
-	zynq_clk_register_pll(&clks[armpll_clk], &slcr_base->arm_pll_ctrl,
-			      CONFIG_ZYNQ_PS_CLK_FREQ);
-	zynq_clk_register_pll(&clks[ddrpll_clk], &slcr_base->ddr_pll_ctrl,
-			      CONFIG_ZYNQ_PS_CLK_FREQ);
-	zynq_clk_register_pll(&clks[iopll_clk], &slcr_base->io_pll_ctrl,
-			      CONFIG_ZYNQ_PS_CLK_FREQ);
-
-	init_ddr_clocks();
-	init_cpu_clocks();
-	init_periph_clocks();
-	init_aper_clocks();
-
-	gd->bd->bi_arm_freq = gd->cpu_clk / 1000000;
+	struct clk clk;
+	struct udevice *dev;
+	ulong rate;
+	int i, ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+		DM_GET_DRIVER(zynq_clk), &dev);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < 2; i++) {
+		clk.id = i ? ddr3x_clk : cpu_6or4x_clk;
+		ret = clk_request(dev, &clk);
+		if (ret < 0)
+			return ret;
+
+		rate = clk_get_rate(&clk) / 1000000;
+		if (i)
+			gd->bd->bi_ddr_freq = rate;
+		else
+			gd->bd->bi_arm_freq = rate;
+
+		clk_free(&clk);
+	}
 	gd->bd->bi_dsp_freq = 0;
 
 	return 0;
 }
 
 /**
- * zynq_clk_get_rate() - Get clock rate
- * @clk:	Clock identifier
- * Returns the current clock rate of @clk on success or zero for an invalid
- * clock id.
- */
-unsigned long zynq_clk_get_rate(enum zynq_clk clk)
-{
-	if (clk < 0 || clk >= clk_max)
-		return 0;
-
-	return clks[clk].frequency;
-}
-
-/**
- * zynq_clk_set_rate() - Set clock rate
- * @clk:	Clock identifier
- * @rate:	Requested clock rate
- * Passes on the return value from the clock's set_rate() function or negative
- * errno.
- */
-int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
-{
-	if (clk < 0 || clk >= clk_max)
-		return -ENODEV;
-
-	if (clks[clk].ops.set_rate)
-		return clks[clk].ops.set_rate(&clks[clk], rate);
-
-	return -ENXIO;
-}
-
-/**
  * soc_clk_dump() - Print clock frequencies
  * Returns zero on success
  *
@@ -639,13 +70,35 @@ int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate)
  */
 int soc_clk_dump(void)
 {
-	int i;
+	struct udevice *dev;
+	int i, ret;
+
+	ret = uclass_get_device_by_driver(UCLASS_CLK,
+		DM_GET_DRIVER(zynq_clk), &dev);
+	if (ret)
+		return ret;
 
 	printf("clk\t\tfrequency\n");
 	for (i = 0; i < clk_max; i++) {
 		const char *name = clk_names[i];
-		if (name)
-			printf("%10s%20lu\n", name, zynq_clk_get_rate(i));
+		if (name) {
+			struct clk clk;
+			unsigned long rate;
+
+			clk.id = i;
+			ret = clk_request(dev, &clk);
+			if (ret < 0)
+				return ret;
+
+			rate = clk_get_rate(&clk);
+
+			clk_free(&clk);
+
+			if (rate == (unsigned long)-ENOSYS)
+				printf("%10s%20s\n", name, "unknown");
+			else
+				printf("%10s%20lu\n", name, rate);
+		}
 	}
 
 	return 0;
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index ba9171e..ee1c1a9 100644
--- a/arch/arm/mach-zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
@@ -35,7 +35,6 @@ int arch_cpu_init(void)
 	writel(0xC, &slcr_base->ddr_urgent);
 #endif
 #endif
-	zynq_clk_early_init();
 	zynq_slcr_lock();
 
 	return 0;
diff --git a/arch/arm/mach-zynq/include/mach/clk.h b/arch/arm/mach-zynq/include/mach/clk.h
index 5c2758a..8a039ae 100644
--- a/arch/arm/mach-zynq/include/mach/clk.h
+++ b/arch/arm/mach-zynq/include/mach/clk.h
@@ -20,9 +20,4 @@ enum zynq_clk {
 	uart0_aper_clk, uart1_aper_clk, gpio_aper_clk, lqspi_aper_clk,
 	smc_aper_clk, swdt_clk, dbg_trc_clk, dbg_apb_clk, clk_max};
 
-void zynq_clk_early_init(void);
-int zynq_clk_set_rate(enum zynq_clk clk, unsigned long rate);
-unsigned long zynq_clk_get_rate(enum zynq_clk clk);
-unsigned long get_uart_clk(int dev_id);
-
 #endif
diff --git a/arch/arm/mach-zynq/include/mach/sys_proto.h b/arch/arm/mach-zynq/include/mach/sys_proto.h
index 44c9b50..67238e7 100644
--- a/arch/arm/mach-zynq/include/mach/sys_proto.h
+++ b/arch/arm/mach-zynq/include/mach/sys_proto.h
@@ -10,7 +10,6 @@
 extern void zynq_slcr_lock(void);
 extern void zynq_slcr_unlock(void);
 extern void zynq_slcr_cpu_reset(void);
-extern void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate);
 extern void zynq_slcr_devcfg_disable(void);
 extern void zynq_slcr_devcfg_enable(void);
 extern u32 zynq_slcr_get_boot_mode(void);
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index c1129cd..2a207ae 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -9,7 +9,6 @@
 #include <malloc.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/sys_proto.h>
-#include <asm/arch/clk.h>
 
 #define SLCR_LOCK_MAGIC		0x767B
 #define SLCR_UNLOCK_MAGIC	0xDF0D
@@ -124,27 +123,6 @@ void zynq_slcr_cpu_reset(void)
 	writel(1, &slcr_base->pss_rst_ctrl);
 }
 
-/* Setup clk for network */
-void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
-{
-	int ret;
-
-	zynq_slcr_unlock();
-
-	if (gem_id > 1) {
-		printf("Non existing GEM id %d\n", gem_id);
-		goto out;
-	}
-
-	ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
-	if (ret)
-		goto out;
-
-	udelay(100000);
-out:
-	zynq_slcr_lock();
-}
-
 void zynq_slcr_devcfg_disable(void)
 {
 	u32 reg_val;
diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c
index 0335cbe..b1bb3b8 100644
--- a/arch/arm/mach-zynq/timer.c
+++ b/arch/arm/mach-zynq/timer.c
@@ -61,7 +61,6 @@ int timer_init(void)
 			(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
 			SCUTIMER_CONTROL_ENABLE_MASK;
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	struct udevice *dev;
 	struct clk clk;
 	int ret;
@@ -79,7 +78,6 @@ int timer_init(void)
 	gd->cpu_clk = clk_get_rate(&clk);
 
 	clk_free(&clk);
-#endif
 
 	gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
 
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 8c5c55a..38fb5a4 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -181,9 +181,7 @@ struct zynq_gem_priv {
 	struct phy_device *phydev;
 	int phy_of_handle;
 	struct mii_dev *bus;
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	struct clk clk;
-#endif
 };
 
 static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
@@ -456,7 +454,6 @@ static int zynq_gem_init(struct udevice *dev)
 		break;
 	}
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	ret = clk_set_rate(&priv->clk, clk_rate);
 	if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
 		dev_err(dev, "failed to set tx clock rate\n");
@@ -468,10 +465,6 @@ static int zynq_gem_init(struct udevice *dev)
 		dev_err(dev, "failed to enable tx clock\n");
 		return ret;
 	}
-#else
-	zynq_slcr_gem_clk_setup((ulong)priv->iobase !=
-				ZYNQ_GEM_BASEADDR0, clk_rate);
-#endif
 
 	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
 					ZYNQ_GEM_NWCTRL_TXEN_MASK);
@@ -644,13 +637,11 @@ 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);
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get clock\n");
 		return -EINVAL;
 	}
-#endif
 
 	priv->bus = mdio_alloc();
 	priv->bus->read = zynq_gem_miiphy_read;
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 4f6e7e4..a2967c0 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -15,7 +15,6 @@
 #include <asm/io.h>
 #include <linux/compiler.h>
 #include <serial.h>
-#include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -111,7 +110,6 @@ int zynq_serial_setbrg(struct udevice *dev, int baudrate)
 	struct zynq_uart_priv *priv = dev_get_priv(dev);
 	unsigned long clock;
 
-#if defined(CONFIG_CLK) || defined(CONFIG_SPL_CLK)
 	int ret;
 	struct clk clk;
 
@@ -133,9 +131,7 @@ int zynq_serial_setbrg(struct udevice *dev, int baudrate)
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}
-#else
-	clock = get_uart_clk(0);
-#endif
+
 	_uart_zynq_serial_setbrg(priv->regs, clock, baudrate);
 
 	return 0;
diff --git a/include/configs/topic_miami.h b/include/configs/topic_miami.h
index 3b0fa29..a1ccc42 100644
--- a/include/configs/topic_miami.h
+++ b/include/configs/topic_miami.h
@@ -10,8 +10,6 @@
 #ifndef __CONFIG_TOPIC_MIAMI_H
 #define __CONFIG_TOPIC_MIAMI_H
 
-#define CONFIG_ZYNQ_PS_CLK_FREQ		33333333UL
-
 #define CONFIG_ZYNQ_I2C0
 #define CONFIG_ZYNQ_I2C1
 
diff --git a/include/configs/zynq_zybo.h b/include/configs/zynq_zybo.h
index b9ff391..1488fd8 100644
--- a/include/configs/zynq_zybo.h
+++ b/include/configs/zynq_zybo.h
@@ -20,9 +20,6 @@
 #define CONFIG_DISPLAY
 #define CONFIG_I2C_EDID
 
-/* Define ZYBO PS Clock Frequency to 50MHz */
-#define CONFIG_ZYNQ_PS_CLK_FREQ	50000000UL
-
 #include <configs/zynq-common.h>
 
 #endif /* __CONFIG_ZYNQ_ZYBO_H */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 4935b91..99a1de5 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -6955,7 +6955,6 @@ CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET
 CONFIG_ZYNQ_HISPD_BROKEN
 CONFIG_ZYNQ_I2C0
 CONFIG_ZYNQ_I2C1
-CONFIG_ZYNQ_PS_CLK_FREQ
 CONFIG_ZYNQ_SDHCI0
 CONFIG_ZYNQ_SDHCI1
 CONFIG_ZYNQ_SDHCI_MAX_FREQ
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 08/10] clk: zynq: Add optional ethernet emio clock source support
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (6 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 07/10] zynq: Move zynq to clock framework stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 09/10] mmc: zynq: Determine base clock frequency via clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Add support for the optional ethernet emio clock source to the zynq
clock framework driver.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

---

Changes in v2:
- Return a error and print a debug message if a gem emio rx clock
  source is unknown
- Correct the checks for valid clock objects

 drivers/clk/clk_zynq.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index a070f01..6edc4dc 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -48,6 +48,9 @@ enum zynq_clk_rclk {mio_clk, emio_clk};
 
 struct zynq_clk_priv {
 	ulong ps_clk_freq;
+#ifndef CONFIG_SPL_BUILD
+	struct clk gem_emio_clk[2];
+#endif
 };
 
 static void *zynq_clk_get_register(enum zynq_clk id)
@@ -267,9 +270,15 @@ static ulong zynq_clk_get_peripheral_rate(struct zynq_clk_priv *priv,
 #ifndef CONFIG_SPL_BUILD
 static ulong zynq_clk_get_gem_rate(struct zynq_clk_priv *priv, enum zynq_clk id)
 {
+	struct clk *parent;
+
 	if (zynq_clk_get_gem_rclk(id) == mio_clk)
 		return zynq_clk_get_peripheral_rate(priv, id, true);
 
+	parent = &priv->gem_emio_clk[id - gem0_clk];
+	if (parent->dev)
+		return clk_get_rate(parent);
+
 	debug("%s: gem%d emio rx clock source unknown\n", __func__,
 	      id - gem0_clk);
 
@@ -340,9 +349,15 @@ static ulong zynq_clk_set_peripheral_rate(struct zynq_clk_priv *priv,
 static ulong zynq_clk_set_gem_rate(struct zynq_clk_priv *priv, enum zynq_clk id,
 				   ulong rate)
 {
+	struct clk *parent;
+
 	if (zynq_clk_get_gem_rclk(id) == mio_clk)
 		return zynq_clk_set_peripheral_rate(priv, id, rate, true);
 
+	parent = &priv->gem_emio_clk[id - gem0_clk];
+	if (parent->dev)
+		return clk_set_rate(parent, rate);
+
 	debug("%s: gem%d emio rx clock source unknown\n", __func__,
 	      id - gem0_clk);
 
@@ -436,6 +451,20 @@ static struct clk_ops zynq_clk_ops = {
 static int zynq_clk_probe(struct udevice *dev)
 {
 	struct zynq_clk_priv *priv = dev_get_priv(dev);
+#ifndef CONFIG_SPL_BUILD
+	unsigned int i;
+	char name[16];
+	int ret;
+
+	for (i = 0; i < 2; i++) {
+		sprintf(name, "gem%d_emio_clk", i);
+		ret = clk_get_by_name(dev, name, &priv->gem_emio_clk[i]);
+		if (ret < 0 && ret != -FDT_ERR_NOTFOUND) {
+			dev_err(dev, "failed to get %s clock\n", name);
+			return ret;
+		}
+	}
+#endif
 
 	priv->ps_clk_freq = fdtdec_get_uint(gd->fdt_blob, dev->of_offset,
 					    "ps-clk-frequency", 33333333UL);
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 09/10] mmc: zynq: Determine base clock frequency via clock framework
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (7 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 08/10] clk: zynq: Add optional ethernet emio clock source support stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-19 11:35   ` Jaehoon Chung
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 10/10] mmc: zynq: Add fdt max-frequency support stefan.herbrechtsmeier at weidmueller.com
  2017-02-06 10:14 ` [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework Stefan.Herbrechtsmeier at weidmueller.com
  10 siblings, 1 reply; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

The zynq_sdhci controller driver use CONFIG_ZYNQ_SDHCI_MAX_FREQ as base
clock frequency but this clock is not fixed and depends on the hardware
configuration. Additionally the value of CONFIG_ZYNQ_SDHCI_MAX_FREQ
doesn't match the real base clock frequency of SDIO_FREQ. Use the clock
framework to determine the frequency at run time.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

---

Changes in v2:
- Add patch to determine base clock frequency of zynq mmc driver via
  clock framework

 drivers/mmc/zynq_sdhci.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 69efa38..c73a4d3 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -6,6 +6,7 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#include <clk.h>
 #include <common.h>
 #include <dm.h>
 #include <fdtdec.h>
@@ -27,8 +28,29 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 	struct sdhci_host *host = dev_get_priv(dev);
+	struct clk clk;
+	unsigned long clock;
 	int ret;
 
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to get clock\n");
+		return ret;
+	}
+
+	clock = clk_get_rate(&clk);
+	if (IS_ERR_VALUE(clock)) {
+		dev_err(dev, "failed to get rate\n");
+		return clock;
+	}
+	debug("%s: CLK %ld\n", __func__, clock);
+
+	ret = clk_enable(&clk);
+	if (ret && ret != -ENOSYS) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+
 	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
 		       SDHCI_QUIRK_BROKEN_R1B;
 
@@ -36,9 +58,9 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
 #endif
 
-	host->max_clk = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
+	host->max_clk = clock;
 
-	ret = sdhci_setup_cfg(&plat->cfg, host, 0,
+	ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ZYNQ_SDHCI_MAX_FREQ,
 			      CONFIG_ZYNQ_SDHCI_MIN_FREQ);
 	host->mmc = &plat->mmc;
 	if (ret)
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 10/10] mmc: zynq: Add fdt max-frequency support
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (8 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 09/10] mmc: zynq: Determine base clock frequency via clock framework stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-17 15:27 ` stefan.herbrechtsmeier at weidmueller.com
  2017-01-19 11:36   ` Jaehoon Chung
  2017-02-06 10:14 ` [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework Stefan.Herbrechtsmeier at weidmueller.com
  10 siblings, 1 reply; 22+ messages in thread
From: stefan.herbrechtsmeier at weidmueller.com @ 2017-01-17 15:27 UTC (permalink / raw)
  To: u-boot

From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

The maximum supported peripheral clock frequency of the zynq depends on
the IO routing. The MIO and EMIO support a maximum frequency of 50 MHz
respectively 25 MHz. Use the max-frequency value of the device tree to
determine the maximal supported peripheral clock frequency.

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
Acked-by: Michal Simek <michal.simek@xilinx.com>

---

Changes in v2:
- Add patch to add fdt max-frequency support to zynq mmc driver

 drivers/mmc/zynq_sdhci.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index c73a4d3..28cedf0 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -14,6 +14,8 @@
 #include <malloc.h>
 #include <sdhci.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #ifndef CONFIG_ZYNQ_SDHCI_MIN_FREQ
 # define CONFIG_ZYNQ_SDHCI_MIN_FREQ	0
 #endif
@@ -21,6 +23,7 @@
 struct arasan_sdhci_plat {
 	struct mmc_config cfg;
 	struct mmc mmc;
+	unsigned int f_max;
 };
 
 static int arasan_sdhci_probe(struct udevice *dev)
@@ -60,7 +63,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
 
 	host->max_clk = clock;
 
-	ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ZYNQ_SDHCI_MAX_FREQ,
+	ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
 			      CONFIG_ZYNQ_SDHCI_MIN_FREQ);
 	host->mmc = &plat->mmc;
 	if (ret)
@@ -74,11 +77,15 @@ static int arasan_sdhci_probe(struct udevice *dev)
 
 static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
 {
+	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
 	struct sdhci_host *host = dev_get_priv(dev);
 
 	host->name = dev->name;
 	host->ioaddr = (void *)dev_get_addr(dev);
 
+	plat->f_max = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+				"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
+
 	return 0;
 }
 
-- 
2.7.4



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-18 21:48   ` Joe Hershberger
  0 siblings, 0 replies; 22+ messages in thread
From: Joe Hershberger @ 2017-01-18 21:48 UTC (permalink / raw)
  To: u-boot

On Tue, Jan 17, 2017 at 9:27 AM,
<stefan.herbrechtsmeier@weidmueller.com> wrote:
> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>
> The gem[0-1]_rclk_ctrl registers control the source of the rx clock,
> control and data signals and configure via ps7_init function. Don't
> overwrite the register with the default value.
>
> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 02/10] net: zynq: Add clk framework support to zynq ethernet driver
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 02/10] net: zynq: Add clk framework support to zynq ethernet driver stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-18 21:50   ` Joe Hershberger
  0 siblings, 0 replies; 22+ messages in thread
From: Joe Hershberger @ 2017-01-18 21:50 UTC (permalink / raw)
  To: u-boot

On Tue, Jan 17, 2017 at 9:27 AM,
<stefan.herbrechtsmeier@weidmueller.com> wrote:
> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
>
> If available use the clock framework to set the tx clock rate of the
> zynq ethernet controller.
>
> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 09/10] mmc: zynq: Determine base clock frequency via clock framework
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 09/10] mmc: zynq: Determine base clock frequency via clock framework stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-19 11:35   ` Jaehoon Chung
  0 siblings, 0 replies; 22+ messages in thread
From: Jaehoon Chung @ 2017-01-19 11:35 UTC (permalink / raw)
  To: u-boot

On 01/18/2017 12:27 AM, stefan.herbrechtsmeier at weidmueller.com wrote:
> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
> 
> The zynq_sdhci controller driver use CONFIG_ZYNQ_SDHCI_MAX_FREQ as base
> clock frequency but this clock is not fixed and depends on the hardware
> configuration. Additionally the value of CONFIG_ZYNQ_SDHCI_MAX_FREQ
> doesn't match the real base clock frequency of SDIO_FREQ. Use the clock
> framework to determine the frequency at run time.
> 
> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> 
> ---
> 
> Changes in v2:
> - Add patch to determine base clock frequency of zynq mmc driver via
>   clock framework
> 
>  drivers/mmc/zynq_sdhci.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
> index 69efa38..c73a4d3 100644
> --- a/drivers/mmc/zynq_sdhci.c
> +++ b/drivers/mmc/zynq_sdhci.c
> @@ -6,6 +6,7 @@
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> +#include <clk.h>
>  #include <common.h>
>  #include <dm.h>
>  #include <fdtdec.h>
> @@ -27,8 +28,29 @@ static int arasan_sdhci_probe(struct udevice *dev)
>  	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
>  	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
>  	struct sdhci_host *host = dev_get_priv(dev);
> +	struct clk clk;
> +	unsigned long clock;
>  	int ret;
>  
> +	ret = clk_get_by_index(dev, 0, &clk);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to get clock\n");
> +		return ret;
> +	}
> +
> +	clock = clk_get_rate(&clk);
> +	if (IS_ERR_VALUE(clock)) {
> +		dev_err(dev, "failed to get rate\n");
> +		return clock;
> +	}
> +	debug("%s: CLK %ld\n", __func__, clock);
> +
> +	ret = clk_enable(&clk);
> +	if (ret && ret != -ENOSYS) {
> +		dev_err(dev, "failed to enable clock\n");
> +		return ret;
> +	}
> +
>  	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
>  		       SDHCI_QUIRK_BROKEN_R1B;
>  
> @@ -36,9 +58,9 @@ static int arasan_sdhci_probe(struct udevice *dev)
>  	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
>  #endif
>  
> -	host->max_clk = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
> +	host->max_clk = clock;
>  
> -	ret = sdhci_setup_cfg(&plat->cfg, host, 0,
> +	ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ZYNQ_SDHCI_MAX_FREQ,
>  			      CONFIG_ZYNQ_SDHCI_MIN_FREQ);
>  	host->mmc = &plat->mmc;
>  	if (ret)
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 10/10] mmc: zynq: Add fdt max-frequency support
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 10/10] mmc: zynq: Add fdt max-frequency support stefan.herbrechtsmeier at weidmueller.com
@ 2017-01-19 11:36   ` Jaehoon Chung
  0 siblings, 0 replies; 22+ messages in thread
From: Jaehoon Chung @ 2017-01-19 11:36 UTC (permalink / raw)
  To: u-boot

On 01/18/2017 12:27 AM, stefan.herbrechtsmeier at weidmueller.com wrote:
> From: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
> 
> The maximum supported peripheral clock frequency of the zynq depends on
> the IO routing. The MIO and EMIO support a maximum frequency of 50 MHz
> respectively 25 MHz. Use the max-frequency value of the device tree to
> determine the maximal supported peripheral clock frequency.
> 
> Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
> Acked-by: Michal Simek <michal.simek@xilinx.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> 
> ---
> 
> Changes in v2:
> - Add patch to add fdt max-frequency support to zynq mmc driver
> 
>  drivers/mmc/zynq_sdhci.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
> index c73a4d3..28cedf0 100644
> --- a/drivers/mmc/zynq_sdhci.c
> +++ b/drivers/mmc/zynq_sdhci.c
> @@ -14,6 +14,8 @@
>  #include <malloc.h>
>  #include <sdhci.h>
>  
> +DECLARE_GLOBAL_DATA_PTR;
> +
>  #ifndef CONFIG_ZYNQ_SDHCI_MIN_FREQ
>  # define CONFIG_ZYNQ_SDHCI_MIN_FREQ	0
>  #endif
> @@ -21,6 +23,7 @@
>  struct arasan_sdhci_plat {
>  	struct mmc_config cfg;
>  	struct mmc mmc;
> +	unsigned int f_max;
>  };
>  
>  static int arasan_sdhci_probe(struct udevice *dev)
> @@ -60,7 +63,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
>  
>  	host->max_clk = clock;
>  
> -	ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ZYNQ_SDHCI_MAX_FREQ,
> +	ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
>  			      CONFIG_ZYNQ_SDHCI_MIN_FREQ);
>  	host->mmc = &plat->mmc;
>  	if (ret)
> @@ -74,11 +77,15 @@ static int arasan_sdhci_probe(struct udevice *dev)
>  
>  static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
>  {
> +	struct arasan_sdhci_plat *plat = dev_get_platdata(dev);
>  	struct sdhci_host *host = dev_get_priv(dev);
>  
>  	host->name = dev->name;
>  	host->ioaddr = (void *)dev_get_addr(dev);
>  
> +	plat->f_max = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
> +				"max-frequency", CONFIG_ZYNQ_SDHCI_MAX_FREQ);
> +
>  	return 0;
>  }
>  
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
                   ` (9 preceding siblings ...)
  2017-01-17 15:27 ` [U-Boot] [PATCH v2 10/10] mmc: zynq: Add fdt max-frequency support stefan.herbrechtsmeier at weidmueller.com
@ 2017-02-06 10:14 ` Stefan.Herbrechtsmeier at weidmueller.com
  2017-02-06 10:29   ` Michal Simek
  10 siblings, 1 reply; 22+ messages in thread
From: Stefan.Herbrechtsmeier at weidmueller.com @ 2017-02-06 10:14 UTC (permalink / raw)
  To: u-boot

Hi Michal,

> -----Urspr?ngliche Nachricht-----
> Von: stefan.herbrechtsmeier at weidmueller.com
>  
> The old platform clock driver use a dynamic array which is filled at
> every boot with static clock tree information and unused clock rates.
> This needs much memory and complicates the strip down for the SPL.
> The new clock framework driver contains the tree information in
> functions and reads clock rates on demand.
> 

Any comments on this patch series?

Regards,
  Stefan



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-02-06 10:14 ` [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework Stefan.Herbrechtsmeier at weidmueller.com
@ 2017-02-06 10:29   ` Michal Simek
  2017-02-17  7:33     ` Stefan.Herbrechtsmeier at weidmueller.com
  0 siblings, 1 reply; 22+ messages in thread
From: Michal Simek @ 2017-02-06 10:29 UTC (permalink / raw)
  To: u-boot

Hi Stefan,

On 6.2.2017 11:14, Stefan.Herbrechtsmeier at weidmueller.com wrote:
> Hi Michal,
> 
>> -----Urspr?ngliche Nachricht-----
>> Von: stefan.herbrechtsmeier at weidmueller.com
>>  
>> The old platform clock driver use a dynamic array which is filled at
>> every boot with static clock tree information and unused clock rates.
>> This needs much memory and complicates the strip down for the SPL.
>> The new clock framework driver contains the tree information in
>> functions and reads clock rates on demand.
>>
> 
> Any comments on this patch series?

I was sick the whole last week and catching emails.
I have tried it on zc702 and it didn't work for me that's why I will
have closer look hopefully this week. Definitely sorry for delay.

Thanks,
Michal

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-02-06 10:29   ` Michal Simek
@ 2017-02-17  7:33     ` Stefan.Herbrechtsmeier at weidmueller.com
  2017-02-17  9:21       ` Michal Simek
  0 siblings, 1 reply; 22+ messages in thread
From: Stefan.Herbrechtsmeier at weidmueller.com @ 2017-02-17  7:33 UTC (permalink / raw)
  To: u-boot

Hi Michal,

> -----Urspr?ngliche Nachricht-----
> Von: Michal Simek [mailto:michal.simek at xilinx.com]
> > 
> Hi Stefan,
> 
> On 6.2.2017 11:14, Stefan.Herbrechtsmeier at weidmueller.com wrote:
> > Hi Michal,
> >
> >> -----Urspr?ngliche Nachricht-----
> >> Von: stefan.herbrechtsmeier at weidmueller.com
> >>
> >> The old platform clock driver use a dynamic array which is filled at
> >> every boot with static clock tree information and unused clock
> rates.
> >> This needs much memory and complicates the strip down for the SPL.
> >> The new clock framework driver contains the tree information in
> >> functions and reads clock rates on demand.
> >>
> >
> > Any comments on this patch series?
> 
> I was sick the whole last week and catching emails.
> I have tried it on zc702 and it didn't work for me that's why I will
> have closer look hopefully this week. Definitely sorry for delay.

Could you describe the problem. Maybe I could help.

Regards
  Stefan



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-02-17  7:33     ` Stefan.Herbrechtsmeier at weidmueller.com
@ 2017-02-17  9:21       ` Michal Simek
  2017-02-17 11:32         ` Michal Simek
  0 siblings, 1 reply; 22+ messages in thread
From: Michal Simek @ 2017-02-17  9:21 UTC (permalink / raw)
  To: u-boot

On 17.2.2017 08:33, Stefan.Herbrechtsmeier at weidmueller.com wrote:
> Hi Michal,
> 
>> -----Urspr?ngliche Nachricht-----
>> Von: Michal Simek [mailto:michal.simek at xilinx.com]
>>>
>> Hi Stefan,
>>
>> On 6.2.2017 11:14, Stefan.Herbrechtsmeier at weidmueller.com wrote:
>>> Hi Michal,
>>>
>>>> -----Urspr?ngliche Nachricht-----
>>>> Von: stefan.herbrechtsmeier at weidmueller.com
>>>>
>>>> The old platform clock driver use a dynamic array which is filled at
>>>> every boot with static clock tree information and unused clock
>> rates.
>>>> This needs much memory and complicates the strip down for the SPL.
>>>> The new clock framework driver contains the tree information in
>>>> functions and reads clock rates on demand.
>>>>
>>>
>>> Any comments on this patch series?
>>
>> I was sick the whole last week and catching emails.
>> I have tried it on zc702 and it didn't work for me that's why I will
>> have closer look hopefully this week. Definitely sorry for delay.
> 
> Could you describe the problem. Maybe I could help.

On zybo I am getting this.

failed to get clock
failed to get clock
No serial driver found

Thanks,
Michal

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-02-17  9:21       ` Michal Simek
@ 2017-02-17 11:32         ` Michal Simek
  2017-02-17 11:51           ` Stefan.Herbrechtsmeier at weidmueller.com
  0 siblings, 1 reply; 22+ messages in thread
From: Michal Simek @ 2017-02-17 11:32 UTC (permalink / raw)
  To: u-boot

On 17.2.2017 10:21, Michal Simek wrote:
> On 17.2.2017 08:33, Stefan.Herbrechtsmeier at weidmueller.com wrote:
>> Hi Michal,
>>
>>> -----Urspr?ngliche Nachricht-----
>>> Von: Michal Simek [mailto:michal.simek at xilinx.com]
>>>>
>>> Hi Stefan,
>>>
>>> On 6.2.2017 11:14, Stefan.Herbrechtsmeier at weidmueller.com wrote:
>>>> Hi Michal,
>>>>
>>>>> -----Urspr?ngliche Nachricht-----
>>>>> Von: stefan.herbrechtsmeier at weidmueller.com
>>>>>
>>>>> The old platform clock driver use a dynamic array which is filled at
>>>>> every boot with static clock tree information and unused clock
>>> rates.
>>>>> This needs much memory and complicates the strip down for the SPL.
>>>>> The new clock framework driver contains the tree information in
>>>>> functions and reads clock rates on demand.
>>>>>
>>>>
>>>> Any comments on this patch series?
>>>
>>> I was sick the whole last week and catching emails.
>>> I have tried it on zc702 and it didn't work for me that's why I will
>>> have closer look hopefully this week. Definitely sorry for delay.
>>
>> Could you describe the problem. Maybe I could help.
> 
> On zybo I am getting this.
> 
> failed to get clock
> failed to get clock
> No serial driver found

Interesting. I have rebased trees and it started to work on
zybo/zc702/zc706/microzed.

I will rebuild all targets and let you know.

Thanks,
Michal

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-02-17 11:32         ` Michal Simek
@ 2017-02-17 11:51           ` Stefan.Herbrechtsmeier at weidmueller.com
  2017-02-17 12:31             ` Michal Simek
  0 siblings, 1 reply; 22+ messages in thread
From: Stefan.Herbrechtsmeier at weidmueller.com @ 2017-02-17 11:51 UTC (permalink / raw)
  To: u-boot

> -----Urspr?ngliche Nachricht-----
> Von: Michal Simek [mailto:michal.simek at xilinx.com]
> 
> On 17.2.2017 10:21, Michal Simek wrote:
> > On 17.2.2017 08:33, Stefan.Herbrechtsmeier at weidmueller.com wrote:
> >> Hi Michal,
> >>
> >>> -----Urspr?ngliche Nachricht-----
> >>> Von: Michal Simek [mailto:michal.simek at xilinx.com]
> >>>>
> >>> Hi Stefan,
> >>>
> >>> On 6.2.2017 11:14, Stefan.Herbrechtsmeier at weidmueller.com wrote:
> >>>> Hi Michal,
> >>>>
> >>>>> -----Urspr?ngliche Nachricht-----
> >>>>> Von: stefan.herbrechtsmeier at weidmueller.com
> >>>>>
> >>>>> The old platform clock driver use a dynamic array which is filled
> >>>>> at every boot with static clock tree information and unused clock
> >>> rates.
> >>>>> This needs much memory and complicates the strip down for the
> SPL.
> >>>>> The new clock framework driver contains the tree information in
> >>>>> functions and reads clock rates on demand.
> >>>>>
> >>>>
> >>>> Any comments on this patch series?
> >>>
> >>> I was sick the whole last week and catching emails.
> >>> I have tried it on zc702 and it didn't work for me that's why I
> will
> >>> have closer look hopefully this week. Definitely sorry for delay.
> >>
> >> Could you describe the problem. Maybe I could help.
> >
> > On zybo I am getting this.
> >
> > failed to get clock
> > failed to get clock
> > No serial driver found
> 
> Interesting. I have rebased trees and it started to work on
> zybo/zc702/zc706/microzed.
> 

I assume a SPL malloc problem because of the additional "u-boot,dm-pre-reloc" entries inside the device tree.

Maybe we need to increase the CONFIG_SYS_SPL_MALLOC_SIZE.

Regards,
  Stefan



Kommanditgesellschaft - Sitz: Detmold - Amtsgericht Lemgo HRA 2790 - 
Komplement?rin: Weidm?ller Interface F?hrungsgesellschaft mbH - 
Sitz: Detmold - Amtsgericht Lemgo HRB 3924; 
Gesch?ftsf?hrer: Jos? Carlos ?lvarez Tobar, Elke Eckstein, Dr. Peter K?hler, J?rg Timmermann;
USt-ID-Nr. DE124599660

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework
  2017-02-17 11:51           ` Stefan.Herbrechtsmeier at weidmueller.com
@ 2017-02-17 12:31             ` Michal Simek
  0 siblings, 0 replies; 22+ messages in thread
From: Michal Simek @ 2017-02-17 12:31 UTC (permalink / raw)
  To: u-boot

On 17.2.2017 12:51, Stefan.Herbrechtsmeier at weidmueller.com wrote:
>> -----Urspr?ngliche Nachricht-----
>> Von: Michal Simek [mailto:michal.simek at xilinx.com]
>>
>> On 17.2.2017 10:21, Michal Simek wrote:
>>> On 17.2.2017 08:33, Stefan.Herbrechtsmeier at weidmueller.com wrote:
>>>> Hi Michal,
>>>>
>>>>> -----Urspr?ngliche Nachricht-----
>>>>> Von: Michal Simek [mailto:michal.simek at xilinx.com]
>>>>>>
>>>>> Hi Stefan,
>>>>>
>>>>> On 6.2.2017 11:14, Stefan.Herbrechtsmeier at weidmueller.com wrote:
>>>>>> Hi Michal,
>>>>>>
>>>>>>> -----Urspr?ngliche Nachricht-----
>>>>>>> Von: stefan.herbrechtsmeier at weidmueller.com
>>>>>>>
>>>>>>> The old platform clock driver use a dynamic array which is filled
>>>>>>> at every boot with static clock tree information and unused clock
>>>>> rates.
>>>>>>> This needs much memory and complicates the strip down for the
>> SPL.
>>>>>>> The new clock framework driver contains the tree information in
>>>>>>> functions and reads clock rates on demand.
>>>>>>>
>>>>>>
>>>>>> Any comments on this patch series?
>>>>>
>>>>> I was sick the whole last week and catching emails.
>>>>> I have tried it on zc702 and it didn't work for me that's why I
>> will
>>>>> have closer look hopefully this week. Definitely sorry for delay.
>>>>
>>>> Could you describe the problem. Maybe I could help.
>>>
>>> On zybo I am getting this.
>>>
>>> failed to get clock
>>> failed to get clock
>>> No serial driver found
>>
>> Interesting. I have rebased trees and it started to work on
>> zybo/zc702/zc706/microzed.
>>
> 
> I assume a SPL malloc problem because of the additional "u-boot,dm-pre-reloc" entries inside the device tree.
> 
> Maybe we need to increase the CONFIG_SYS_SPL_MALLOC_SIZE.

Will see - right now that major boards I have tested have no issue. I
have merged the whole series to master branch in my repo and travis is
building it again.

We have rc3 now and I will queue it to next release.

Thanks,
Michal

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2017-02-17 12:31 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-17 15:27 [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 01/10] net: zynq: Don't overwrite gem_rclk_ctrl with default value stefan.herbrechtsmeier at weidmueller.com
2017-01-18 21:48   ` Joe Hershberger
2017-01-17 15:27 ` [U-Boot] [PATCH v2 02/10] net: zynq: Add clk framework support to zynq ethernet driver stefan.herbrechtsmeier at weidmueller.com
2017-01-18 21:50   ` Joe Hershberger
2017-01-17 15:27 ` [U-Boot] [PATCH v2 03/10] zynq: Add clk framework support to zynq timer stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 04/10] zynq: Move static clock names into separate array stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 05/10] zynq: Remove zynq_clk_get_name function stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 06/10] clk: zynq: Add zynq clock framework driver stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 07/10] zynq: Move zynq to clock framework stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 08/10] clk: zynq: Add optional ethernet emio clock source support stefan.herbrechtsmeier at weidmueller.com
2017-01-17 15:27 ` [U-Boot] [PATCH v2 09/10] mmc: zynq: Determine base clock frequency via clock framework stefan.herbrechtsmeier at weidmueller.com
2017-01-19 11:35   ` Jaehoon Chung
2017-01-17 15:27 ` [U-Boot] [PATCH v2 10/10] mmc: zynq: Add fdt max-frequency support stefan.herbrechtsmeier at weidmueller.com
2017-01-19 11:36   ` Jaehoon Chung
2017-02-06 10:14 ` [U-Boot] [PATCH v2 00/10] zynq: clk: Move zynq platform to clock framework Stefan.Herbrechtsmeier at weidmueller.com
2017-02-06 10:29   ` Michal Simek
2017-02-17  7:33     ` Stefan.Herbrechtsmeier at weidmueller.com
2017-02-17  9:21       ` Michal Simek
2017-02-17 11:32         ` Michal Simek
2017-02-17 11:51           ` Stefan.Herbrechtsmeier at weidmueller.com
2017-02-17 12:31             ` Michal Simek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.