[U-Boot] [PATCH 7/8] net: zynq_gem: Calculate clock dividers dynamically

Michal Simek michal.simek at xilinx.com
Wed Jan 22 11:50:59 CET 2014


From: Soren Brinkmann <soren.brinkmann at xilinx.com>

Remove hard coded clock divider setting and use the Zynq clock framework
to dynamically calculate appropriate dividers at run time.

Signed-off-by: Soren Brinkmann <soren.brinkmann at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 arch/arm/cpu/armv7/zynq/slcr.c             | 13 ++++++++-----
 arch/arm/include/asm/arch-zynq/sys_proto.h |  2 +-
 drivers/net/zynq_gem.c                     | 17 +++++++++++------
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c
index 6710d92..d7c1882 100644
--- a/arch/arm/cpu/armv7/zynq/slcr.c
+++ b/arch/arm/cpu/armv7/zynq/slcr.c
@@ -8,6 +8,7 @@
 #include <asm/io.h>
 #include <malloc.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/clk.h>

 #define SLCR_LOCK_MAGIC		0x767B
 #define SLCR_UNLOCK_MAGIC	0xDF0D
@@ -50,8 +51,10 @@ void zynq_slcr_cpu_reset(void)
 }

 /* Setup clk for network */
-void zynq_slcr_gem_clk_setup(u32 gem_id, u32 clk)
+void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
 {
+	int ret;
+
 	zynq_slcr_unlock();

 	if (gem_id > 1) {
@@ -59,14 +62,14 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, u32 clk)
 		goto out;
 	}

+	ret = zynq_clk_set_rate(gem0_clk + gem_id, clk_rate);
+	if (ret)
+		goto out;
+
 	if (gem_id) {
-		/* Set divisors for appropriate frequency in GEM_CLK_CTRL */
-		writel(clk, &slcr_base->gem1_clk_ctrl);
 		/* Configure GEM_RCLK_CTRL */
 		writel(1, &slcr_base->gem1_rclk_ctrl);
 	} else {
-		/* Set divisors for appropriate frequency in GEM_CLK_CTRL */
-		writel(clk, &slcr_base->gem0_clk_ctrl);
 		/* Configure GEM_RCLK_CTRL */
 		writel(1, &slcr_base->gem0_rclk_ctrl);
 	}
diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h
index a485d79..0a2ba05 100644
--- a/arch/arm/include/asm/arch-zynq/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynq/sys_proto.h
@@ -10,7 +10,7 @@
 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, u32 clk);
+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/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 53b7c6f..f4c5134 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -90,6 +90,11 @@
 #define ZYNQ_GEM_TXBUF_EXHAUSTED	0x08000000
 #define ZYNQ_GEM_TXBUF_UNDERRUN		0x10000000

+/* Clock frequencies for different speeds */
+#define ZYNQ_GEM_FREQUENCY_10	2500000UL
+#define ZYNQ_GEM_FREQUENCY_100	25000000UL
+#define ZYNQ_GEM_FREQUENCY_1000	125000000UL
+
 /* Device registers */
 struct zynq_gem_regs {
 	u32 nwctrl; /* Network Control reg */
@@ -270,7 +275,8 @@ static int zynq_gem_setup_mac(struct eth_device *dev)

 static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
 {
-	u32 i, clk = 0;
+	u32 i;
+	unsigned long clk_rate = 0;
 	struct phy_device *phydev;
 	const u32 stat_size = (sizeof(struct zynq_gem_regs) -
 				offsetof(struct zynq_gem_regs, stat)) / 4;
@@ -343,23 +349,22 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
 	case SPEED_1000:
 		writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000,
 		       &regs->nwcfg);
-		clk = (1 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+		clk_rate = ZYNQ_GEM_FREQUENCY_1000;
 		break;
 	case SPEED_100:
 		clrsetbits_le32(&regs->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000,
 				ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100);
-		clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+		clk_rate = ZYNQ_GEM_FREQUENCY_100;
 		break;
 	case SPEED_10:
-		/* FIXME untested */
-		clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
+		clk_rate = ZYNQ_GEM_FREQUENCY_10;
 		break;
 	}

 	/* Change the rclk and clk only not using EMIO interface */
 	if (!priv->emio)
 		zynq_slcr_gem_clk_setup(dev->iobase !=
-					ZYNQ_GEM_BASEADDR0, clk);
+					ZYNQ_GEM_BASEADDR0, clk_rate);

 	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
 					ZYNQ_GEM_NWCTRL_TXEN_MASK);
--
1.8.2.3

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140122/5b98794e/attachment.pgp>


More information about the U-Boot mailing list