Skip to contentSkip to conversation

ZYNQ CLK update + driver changes

PATCH New Michal Simek 1 participant 9 messages Jan 22, 2014

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover ZYNQ CLK update + driver changes

Hi,

this series provide patches for adding clock support for Zynq. I am sending them separately because there are several changes together.
1. Adding DIV_ROUND_CLOSEST macro
2. ARM zynq changes
3. driver changes

This series is based on 7 zynq patches I have sent today.

Thanks,
Michal

Michal Simek (2):
zynq: Update CLK in bdinfo
zynq: timer: Fix hangs if network activity attempted after about one
hour

Soren Brinkmann (6):
common: Provide DIV_ROUND_CLOSEST macro
zynq: Provide a framework to read clock frequencies
zynq: timer: Migrate to zynq clock framework
net: zynq_gem: Move RCLK details out of driver
net: zynq_gem: Calculate clock dividers dynamically
serial_zynq: Migrate to Zynq clock framework

 arch/arm/cpu/armv7/zynq/Makefile           |   1 +
 arch/arm/cpu/armv7/zynq/clk.c              | 643 +++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/zynq/cpu.c              |   2 +
 arch/arm/cpu/armv7/zynq/slcr.c             |  17 +-
 arch/arm/cpu/armv7/zynq/timer.c            |  13 +-
 arch/arm/include/asm/arch-zynq/clk.h       |  29 ++
 arch/arm/include/asm/arch-zynq/hardware.h  |  32 +-
 arch/arm/include/asm/arch-zynq/sys_proto.h |   2 +-
 drivers/net/zynq_gem.c                     |  20 +-
 drivers/serial/serial_zynq.c               |  13 +-
 include/common.h                           |  16 +
 include/configs/zynq-common.h              |   1 +
 12 files changed, 754 insertions(+), 35 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/zynq/clk.c
 create mode 100644 arch/arm/include/asm/arch-zynq/clk.h

--
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/6435532d/attachment.pgp>

#1 lore raw

PATCH 1/8 common: Provide DIV_ROUND_CLOSEST macro

From: Soren Brinkmann <[email protected]>

Provide the DIV_ROUND_CLOSEST macro - taken from the Linux kernel - in common.h

---

 include/common.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
include/common.h +16 -0
index d49c514..ae45836 100644
@@ -964,6 +964,22 @@ static inline phys_addr_t map_to_sysmem(const void *ptr)
 #define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
 #define roundup(x, y)		((((x) + ((y) - 1)) / (y)) * (y))
 
+/*
+ * Divide positive or negative dividend by positive divisor and round
+ * to closest integer. Result is undefined for negative divisors and
+ * for negative dividends if the divisor variable type is unsigned.
+ */
+#define DIV_ROUND_CLOSEST(x, divisor)(			\
+{							\
+	typeof(x) __x = x;				\
+	typeof(divisor) __d = divisor;			\
+	(((typeof(x))-1) > 0 ||				\
+	 ((typeof(divisor))-1) > 0 || (__x) > 0) ?	\
+		(((__x) + ((__d) / 2)) / (__d)) :	\
+		(((__x) - ((__d) / 2)) / (__d));	\
+}							\
+)
+
 #define ALIGN(x,a)		__ALIGN_MASK((x),(typeof(x))(a)-1)
 #define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(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/3a71f1ce/attachment.pgp>

#2 lore raw

PATCH 2/8 zynq: Provide a framework to read clock frequencies

In reply to Michal Simek

From: Soren Brinkmann <[email protected]>

---

 arch/arm/cpu/armv7/zynq/Makefile          |   1 +
 arch/arm/cpu/armv7/zynq/clk.c             | 638 ++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/zynq/cpu.c             |   2 +
 arch/arm/include/asm/arch-zynq/clk.h      |  29 ++
 arch/arm/include/asm/arch-zynq/hardware.h |  32 +-
 include/configs/zynq-common.h             |   1 +
 6 files changed, 701 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/zynq/clk.c
 create mode 100644 arch/arm/include/asm/arch-zynq/clk.h
arch/arm/cpu/armv7/zynq/Makefile +1 -0
index d382d49..3374789 100644
@@ -12,3 +12,4 @@ obj-y	:= timer.o
 obj-y	+= cpu.o
 obj-y	+= ddrc.o
 obj-y	+= slcr.o
+obj-y	+= clk.o
arch/arm/cpu/armv7/zynq/clk.c new file +638 -0

638 lines not on this page · raw message

arch/arm/cpu/armv7/zynq/cpu.c +2 -0
index c771759..5d505dd 100644
@@ -6,6 +6,7 @@
  */
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/clk.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/arch/hardware.h>
 
@@ -35,6 +36,7 @@ int arch_cpu_init(void)
 	writel(0xC, &slcr_base->ddr_urgent);
 #endif
 
+	zynq_clk_early_init();
 	zynq_slcr_lock();
 
 	return 0;
arch/arm/include/asm/arch-zynq/clk.h new file +29 -0
new file mode 100644
index 0000000..250c5bc
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Xilinx Inc.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _ZYNQ_CLK_H_
+#define _ZYNQ_CLK_H_
+
+enum zynq_clk {
+	armpll_clk, ddrpll_clk, iopll_clk,
+	cpu_6or4x_clk, cpu_3or2x_clk, cpu_2x_clk, cpu_1x_clk,
+	ddr2x_clk, ddr3x_clk, dci_clk,
+	lqspi_clk, smc_clk, pcap_clk, gem0_clk, gem1_clk,
+	fclk0_clk, fclk1_clk, fclk2_clk, fclk3_clk, can0_clk, can1_clk,
+	sdio0_clk, sdio1_clk, uart0_clk, uart1_clk, spi0_clk, spi1_clk, dma_clk,
+	usb0_aper_clk, usb1_aper_clk, gem0_aper_clk, gem1_aper_clk,
+	sdio0_aper_clk, sdio1_aper_clk, spi0_aper_clk, spi1_aper_clk,
+	can0_aper_clk, can1_aper_clk, i2c0_aper_clk, i2c1_aper_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);
+const char *zynq_clk_get_name(enum zynq_clk clk);
+unsigned long get_uart_clk(int dev_id);
+
+#endif
arch/arm/include/asm/arch-zynq/hardware.h +30 -2
index d0fba64..39184da 100644
@@ -34,12 +34,40 @@ struct slcr_regs {
 	u32 scl; /* 0x0 */
 	u32 slcr_lock; /* 0x4 */
 	u32 slcr_unlock; /* 0x8 */
-	u32 reserved0[75];
+	u32 reserved0_1[61];
+	u32 arm_pll_ctrl; /* 0x100 */
+	u32 ddr_pll_ctrl; /* 0x104 */
+	u32 io_pll_ctrl; /* 0x108 */
+	u32 reserved0_2[5];
+	u32 arm_clk_ctrl; /* 0x120 */
+	u32 ddr_clk_ctrl; /* 0x124 */
+	u32 dci_clk_ctrl; /* 0x128 */
+	u32 aper_clk_ctrl; /* 0x12c */
+	u32 reserved0_3[2];
 	u32 gem0_rclk_ctrl; /* 0x138 */
 	u32 gem1_rclk_ctrl; /* 0x13c */
 	u32 gem0_clk_ctrl; /* 0x140 */
 	u32 gem1_clk_ctrl; /* 0x144 */
-	u32 reserved1[46];
+	u32 smc_clk_ctrl; /* 0x148 */
+	u32 lqspi_clk_ctrl; /* 0x14c */
+	u32 sdio_clk_ctrl; /* 0x150 */
+	u32 uart_clk_ctrl; /* 0x154 */
+	u32 spi_clk_ctrl; /* 0x158 */
+	u32 can_clk_ctrl; /* 0x15c */
+	u32 can_mioclk_ctrl; /* 0x160 */
+	u32 dbg_clk_ctrl; /* 0x164 */
+	u32 pcap_clk_ctrl; /* 0x168 */
+	u32 reserved0_4[1];
+	u32 fpga0_clk_ctrl; /* 0x170 */
+	u32 reserved0_5[3];
+	u32 fpga1_clk_ctrl; /* 0x180 */
+	u32 reserved0_6[3];
+	u32 fpga2_clk_ctrl; /* 0x190 */
+	u32 reserved0_7[3];
+	u32 fpga3_clk_ctrl; /* 0x1a0 */
+	u32 reserved0_8[8];
+	u32 clk_621_true; /* 0x1c4 */
+	u32 reserved1[14];
 	u32 pss_rst_ctrl; /* 0x200 */
 	u32 reserved2[15];
 	u32 fpga_rst_ctrl; /* 0x240 */
include/configs/zynq-common.h +1 -0
index dfa337f..9666f88 100644
@@ -163,6 +163,7 @@
 #define CONFIG_AUTO_COMPLETE
 #define CONFIG_BOARD_LATE_INIT
 #define CONFIG_SYS_LONGHELP
+#define CONFIG_CLOCKS
 #define CONFIG_SYS_MAXARGS		15 /* max number of command args */
 #define CONFIG_SYS_CBSIZE		256 /* Console I/O Buffer Size */
 #define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \

--
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/29964827/attachment.pgp>

#3 lore raw

PATCH 3/8 zynq: Update CLK in bdinfo

In reply to Michal Simek

ARM has specific clk entries which should be also setup.

---

 arch/arm/cpu/armv7/zynq/clk.c | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/cpu/armv7/zynq/clk.c +5 -0
index 0891a23..ea7a677 100644
@@ -160,6 +160,8 @@ static void init_ddr_clocks(void)
 	clks[dci_clk].frequency = DIV_ROUND_CLOSEST(
 			DIV_ROUND_CLOSEST(prate, div0), div1);
 	clks[dci_clk].name = "dci";
+
+	gd->bd->bi_ddr_freq = clks[dci_clk].frequency;
 }
 
 static void init_cpu_clocks(void)
@@ -592,6 +594,9 @@ int set_cpu_clk_info(void)
 	init_periph_clocks();
 	init_aper_clocks();
 
+	gd->bd->bi_arm_freq = gd->cpu_clk;
+	gd->bd->bi_dsp_freq = 0;
+
 	return 0;
 }
 

--
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/097ec2e5/attachment.pgp>

#4 lore raw

PATCH 4/8 zynq: timer: Migrate to zynq clock framework

In reply to Michal Simek

From: Soren Brinkmann <[email protected]>

Remove hardcoded frequencies in favor of Zynq clock framework.

---

 arch/arm/cpu/armv7/zynq/timer.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
arch/arm/cpu/armv7/zynq/timer.c +7 -4
index 2be253c..78e30a6 100644
@@ -29,6 +29,7 @@
 #include <div64.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/clk.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -48,7 +49,6 @@ static struct scu_timer *timer_base =
 
 #define TIMER_LOAD_VAL 0xFFFFFFFF
 #define TIMER_PRESCALE 255
-#define TIMER_TICK_HZ  (CONFIG_CPU_FREQ_HZ / 2 / TIMER_PRESCALE)
 
 int timer_init(void)
 {
@@ -56,6 +56,8 @@ int timer_init(void)
 			(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
 			SCUTIMER_CONTROL_ENABLE_MASK;
 
+	gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / TIMER_PRESCALE;
+
 	/* Load the timer counter register */
 	writel(0xFFFFFFFF, &timer_base->load);
 
@@ -69,7 +71,7 @@ int timer_init(void)
 
 	/* Reset time */
 	gd->arch.lastinc = readl(&timer_base->counter) /
-					(TIMER_TICK_HZ / CONFIG_SYS_HZ);
+				(gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
 	gd->arch.tbl = 0;
 
 	return 0;
@@ -83,7 +85,8 @@ ulong get_timer_masked(void)
 {
 	ulong now;
 
-	now = readl(&timer_base->counter) / (TIMER_TICK_HZ / CONFIG_SYS_HZ);
+	now = readl(&timer_base->counter) /
+			(gd->arch.timer_rate_hz / CONFIG_SYS_HZ);
 
 	if (gd->arch.lastinc >= now) {
 		/* Normal mode */
@@ -107,7 +110,7 @@ void __udelay(unsigned long usec)
 	if (usec == 0)
 		return;
 
-	countticks = lldiv(TIMER_TICK_HZ * usec, 1000000);
+	countticks = lldiv(gd->arch.timer_rate_hz * usec, 1000000);
 
 	/* decrementing timer */
 	timeend = readl(&timer_base->counter) - countticks;

--
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/fd6f432e/attachment.pgp>

#5 lore raw

PATCH 5/8 zynq: timer: Fix hangs if network activity attempted after about one hour

In reply to Michal Simek

Cortex-A9 MPCore TRM' from ARM (ARM DDI 0407G ID072711) describes in the section 4.1.1 how this value calculation should be done.

This patch fixes the problem if network activity such as ping or tftp is attempted after u-boot has been idle for an hour, it hangs, and cannot control-C out of it.

---

 arch/arm/cpu/armv7/zynq/timer.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/zynq/timer.c +2 -2
index 78e30a6..174e5a1 100644
@@ -56,7 +56,7 @@ int timer_init(void)
 			(TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) |
 			SCUTIMER_CONTROL_ENABLE_MASK;
 
-	gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / TIMER_PRESCALE;
+	gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1);
 
 	/* Load the timer counter register */
 	writel(0xFFFFFFFF, &timer_base->load);
@@ -93,7 +93,7 @@ ulong get_timer_masked(void)
 		gd->arch.tbl += gd->arch.lastinc - now;
 	} else {
 		/* We have an overflow ... */
-		gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now;
+		gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now + 1;
 	}
 	gd->arch.lastinc = now;
 

--
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/884538e5/attachment-0001.pgp>

#6 lore raw

PATCH 6/8 net: zynq_gem: Move RCLK details out of driver

In reply to Michal Simek

From: Soren Brinkmann <[email protected]>

The GEM driver should not need to know about Zynq specific details of RCLK related registers and bitfields in the SLCR. Move those details to the slcr driver.

---

 arch/arm/cpu/armv7/zynq/slcr.c             | 6 +++---
 arch/arm/include/asm/arch-zynq/sys_proto.h | 2 +-
 drivers/net/zynq_gem.c                     | 7 ++-----
 3 files changed, 6 insertions(+), 9 deletions(-)
arch/arm/cpu/armv7/zynq/slcr.c +3 -3
index b4c11c3..6710d92 100644
@@ -50,7 +50,7 @@ void zynq_slcr_cpu_reset(void)
 }
 
 /* Setup clk for network */
-void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
+void zynq_slcr_gem_clk_setup(u32 gem_id, u32 clk)
 {
 	zynq_slcr_unlock();
 
@@ -63,12 +63,12 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
 		/* Set divisors for appropriate frequency in GEM_CLK_CTRL */
 		writel(clk, &slcr_base->gem1_clk_ctrl);
 		/* Configure GEM_RCLK_CTRL */
-		writel(rclk, &slcr_base->gem1_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(rclk, &slcr_base->gem0_rclk_ctrl);
+		writel(1, &slcr_base->gem0_rclk_ctrl);
 	}
 	udelay(100000);
 out:
arch/arm/include/asm/arch-zynq/sys_proto.h +1 -1
index 8f925af..a485d79 100644
@@ -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 rclk, u32 clk);
+extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 clk);
 extern void zynq_slcr_devcfg_disable(void);
 extern void zynq_slcr_devcfg_enable(void);
 extern u32 zynq_slcr_get_boot_mode(void);
drivers/net/zynq_gem.c +2 -5
index 6a017a8..53b7c6f 100644
@@ -270,7 +270,7 @@ static int zynq_gem_setup_mac(struct eth_device *dev)
 
 static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
 {
-	u32 i, rclk, clk = 0;
+	u32 i, clk = 0;
 	struct phy_device *phydev;
 	const u32 stat_size = (sizeof(struct zynq_gem_regs) -
 				offsetof(struct zynq_gem_regs, stat)) / 4;
@@ -343,17 +343,14 @@ 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);
-		rclk = (0 << 4) | (1 << 0);
 		clk = (1 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
 		break;
 	case SPEED_100:
 		clrsetbits_le32(&regs->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000,
 				ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100);
-		rclk = 1 << 0;
 		clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
 		break;
 	case SPEED_10:
-		rclk = 1 << 0;
 		/* FIXME untested */
 		clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0);
 		break;
@@ -362,7 +359,7 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis)
 	/* Change the rclk and clk only not using EMIO interface */
 	if (!priv->emio)
 		zynq_slcr_gem_clk_setup(dev->iobase !=
-					ZYNQ_GEM_BASEADDR0, rclk, clk);
+					ZYNQ_GEM_BASEADDR0, clk);
 
 	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/8dedc082/attachment.pgp>

#7 lore raw

PATCH 7/8 net: zynq_gem: Calculate clock dividers dynamically

In reply to Michal Simek

From: Soren Brinkmann <[email protected]>

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

---

 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(-)
arch/arm/cpu/armv7/zynq/slcr.c +8 -5
index 6710d92..d7c1882 100644
@@ -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);
 	}
arch/arm/include/asm/arch-zynq/sys_proto.h +1 -1
index a485d79..0a2ba05 100644
@@ -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);
drivers/net/zynq_gem.c +11 -6
index 53b7c6f..f4c5134 100644
@@ -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>

#8 lore raw

PATCH 8/8 serial_zynq: Migrate to Zynq clock framework

In reply to Michal Simek

From: Soren Brinkmann <[email protected]>

Remove hard coded frequencies and use Zynq's clock framework to obtain the UART clock frequency.

---

 drivers/serial/serial_zynq.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)
drivers/serial/serial_zynq.c +2 -11
index 9a1ee00..22c6bf0 100644
@@ -10,6 +10,7 @@
 #include <asm/io.h>
 #include <linux/compiler.h>
 #include <serial.h>
+#include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
 
 #define ZYNQ_UART_SR_TXFULL	0x00000010 /* TX FIFO full */
@@ -45,23 +46,13 @@ static struct uart_zynq *uart_zynq_ports[2] = {
 # define CONFIG_ZYNQ_SERIAL_BAUDRATE1	CONFIG_BAUDRATE
 #endif
 
-#if !defined(CONFIG_ZYNQ_SERIAL_CLOCK0)
-# define CONFIG_ZYNQ_SERIAL_CLOCK0	50000000
-#endif
-#if !defined(CONFIG_ZYNQ_SERIAL_CLOCK1)
-# define CONFIG_ZYNQ_SERIAL_CLOCK1	50000000
-#endif
-
 struct uart_zynq_params {
 	u32 baudrate;
-	u32 clock;
 };
 
 static struct uart_zynq_params uart_zynq_ports_param[2] = {
 	[0].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE0,
-	[0].clock = CONFIG_ZYNQ_SERIAL_CLOCK0,
 	[1].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE1,
-	[1].clock = CONFIG_ZYNQ_SERIAL_CLOCK1,
 };
 
 /* Set up the baud rate in gd struct */
@@ -71,7 +62,7 @@ static void uart_zynq_serial_setbrg(const int port)
 	unsigned int calc_bauderror, bdiv, bgen;
 	unsigned long calc_baud = 0;
 	unsigned long baud = uart_zynq_ports_param[port].baudrate;
-	unsigned long clock = uart_zynq_ports_param[port].clock;
+	unsigned long clock = get_uart_clk(port);
 	struct uart_zynq *regs = uart_zynq_ports[port];
 
 	/*                master clock

--
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/93d6bb0d/attachment.pgp>