Skip to contentSkip to conversation

zynq COMMON_CLK support

PATCH In review Josh Cartwright 5 participants 26 messages Oct 29, 2012 – Nov 12, 2012

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

cover zynq COMMON_CLK support

This patchset implements COMMON_CLK support for the zynq. At this point, only the basic fundamental clocks are modelled, and only passively; for rate calculation. of_clk bindings are implemented to allow specifying clock/peripheral relationships in the device tree.

Patch 1 and 2 are a followup to my early patch: "ARM: zynq: move ttc timer code to drivers/clocksource". Patch 1 moves the definition sys_timer definition out of the ttc code, and into the zynq common code. Patch 2 is the actual rename, and makefile cleanup.

Patch 3 adds a description of the second uart to zynq-ep107.dts. I did this pre-split (patch 4), because I felt it might make reviewing easier.

Patch 4 uses zynq-ep107.dts as a reference to create zynq-7000.dtsi, which is intended to be a common dtsi snippet for inclusion in describing zynq-7000 based boards. zynq-zc702.dts is created as an example consumer. The zynq-ep107.dts file is removed entirely (it describes, presumably, a board not available to consumers).

Patch 5 is the real meat; it adds an implementation of the clk models for the PLLs, the CPU clock network, and basic (simplified) clk models for the essential peripherals (UART and the TTC).

Patch 6 removes CONFIG_OF conditional code from the xilinx uart driver. The zynq kernel requires CONFIG_OF, and this hardware is not currently used on any other non CONFIG_OF platform.

Patch 7 adds support to the xilinx_uartps driver to allow getting clock rate information form the device tree.

Patch 8 implements DT support for the ttc, including pulling clock tree info.

---
There are some specific concerns that I had that I would like some guidance on:

Two identical timers on the board have historically been statically allocated to act as the system clocksource, and the clockevent_device. With patch 8, this distinction is done in the device tree by tweaking with the compatible properties of which of the timers you want used for what purpose.

I feel, however, that this is an abuse of the device tree, which should only be used to describe hardware, not to layout a policy on how the hardware is used.

So, if it's not in the device tree, then where? Do I go back to the static allocation routine, such that the first matching ttc node in the tree becomes the clockevent_device, and the second one a clocksource? That seems like a hack.

Is it somehow possible to have all of the timers registered as both a clocksource and a clockevent_device, and have some higher level logic make the policy decision as to which timer is used for what?

An additional question regarding of_clk bindings:

	my_clock {
		#clock-cells = <0>;
		clock-output-names = "my_out_clock";
	};
	node_a {
		clocks = <&clk>;
		clock-names = "my_clock";
		clock-ranges;

		node_b {
			/* ... */
		};
	};

In this scenario, should I be expecting of_clk_get(node_b, 0) to retrieve a handle to parent's consumed clock (due to clock-ranges)? I could make this work using of_clk_get_by_name(node_b, "my_clock"), but I was somewhat surprised the former didn't work.

Thanks (and sorry for the novel),
Josh

---
Josh Cartwright (8):
ARM: zynq: move arm-specific sys_timer out of ttc
ARM: zynq: move ttc timer code to drivers/clocksource
ARM: zynq: dts: add description of the second uart
ARM: zynq: dts: split up device tree
ARM: zynq: add COMMON_CLK support
serial: xilinx_uartps: kill CONFIG_OF conditional
serial: xilinx_uartps: get clock rate info from dts
clocksource: xilinx_ttc: add OF_CLK support

 .../devicetree/bindings/clock/zynq-7000.txt        |  55 ++++
 arch/arm/Kconfig                                   |   1 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/zynq-7000.dtsi                   | 166 ++++++++++
 arch/arm/boot/dts/zynq-ep107.dts                   |  63 ----
 arch/arm/boot/dts/zynq-zc702.dts                   |  44 +++
 arch/arm/mach-zynq/Makefile                        |   2 +-
 arch/arm/mach-zynq/common.c                        |  29 +-
 arch/arm/mach-zynq/timer.c                         | 298 -----------------
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-zynq.c                             | 355 +++++++++++++++++++++
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/xilinx_ttc.c                   | 326 +++++++++++++++++++
 drivers/tty/serial/xilinx_uartps.c                 |  39 +--
 include/linux/clk/zynq.h                           |  24 ++
 .../common.h => include/linux/xilinx_ttc.h         |   8 +-
 16 files changed, 1022 insertions(+), 391 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/zynq-7000.txt
 create mode 100644 arch/arm/boot/dts/zynq-7000.dtsi
 delete mode 100644 arch/arm/boot/dts/zynq-ep107.dts
 create mode 100644 arch/arm/boot/dts/zynq-zc702.dts
 delete mode 100644 arch/arm/mach-zynq/timer.c
 create mode 100644 drivers/clk/clk-zynq.c
 create mode 100644 drivers/clocksource/xilinx_ttc.c
 create mode 100644 include/linux/clk/zynq.h
 rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (81%)
Signature · 1 line
1.8.0
#1 lore raw

PATCH 1/8 ARM: zynq: move arm-specific sys_timer out of ttc

Move the sys_timer definition out of ttc driver and make it part of the common zynq code. This is preparation for renaming and COMMON_CLK support.

---
 arch/arm/mach-zynq/common.c | 13 +++++++++++++
 arch/arm/mach-zynq/common.h |  4 +---
 arch/arm/mach-zynq/timer.c  | 10 +---------
 3 files changed, 15 insertions(+), 12 deletions(-)
arch/arm/mach-zynq/common.c +13 -0
index ba8d14f..6f058258 100644
@@ -25,6 +25,7 @@
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/mach/time.h>
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/hardware/gic.h>
@@ -93,6 +94,18 @@ static struct map_desc io_desc[] __initdata = {
 
 };
 
+static void __init xilinx_zynq_timer_init(void)
+{
+	xttcpss_timer_init();
+}
+
+/*
+ * Instantiate and initialize the system timer structure
+ */
+static struct sys_timer xttcpss_sys_timer = {
+	.init		= xilinx_zynq_timer_init,
+};
+
 /**
  * xilinx_map_io() - Create memory mappings needed for early I/O.
  */
arch/arm/mach-zynq/common.h +1 -3
index a009644..954b91c 100644
@@ -17,8 +17,6 @@
 #ifndef __MACH_ZYNQ_COMMON_H__
 #define __MACH_ZYNQ_COMMON_H__
 
-#include <asm/mach/time.h>
-
-extern struct sys_timer xttcpss_sys_timer;
+void __init xttcpss_timer_init(void);
 
 #endif
arch/arm/mach-zynq/timer.c +1 -9
index c2c96cc..c93cbe5 100644
@@ -24,7 +24,6 @@
 #include <linux/clockchips.h>
 #include <linux/io.h>
 
-#include <asm/mach/time.h>
 #include <mach/zynq_soc.h>
 #include "common.h"
 
@@ -269,7 +268,7 @@ static struct clock_event_device xttcpss_clockevent = {
  * Initializes the timer hardware and register the clock source and clock event
  * timers with Linux kernal timer framework
  **/
-static void __init xttcpss_timer_init(void)
+void __init xttcpss_timer_init(void)
 {
 	xttcpss_timer_hardware_init();
 	clocksource_register_hz(&clocksource_xttcpss, TIMER_RATE);
@@ -289,10 +288,3 @@ static void __init xttcpss_timer_init(void)
 	xttcpss_clockevent.cpumask = cpumask_of(0);
 	clockevents_register_device(&xttcpss_clockevent);
 }
-
-/*
- * Instantiate and initialize the system timer structure
- */
-struct sys_timer xttcpss_sys_timer = {
-	.init		= xttcpss_timer_init,
-};
Signature · 1 line
1.8.0
Tested-by on v1 1/8
#2 lore raw

Re: [PATCH 1/8] ARM: zynq: move arm-specific sys_timer out of ttc

2012/10/31 Josh Cartwright <[email protected]>:

Quoted 11 lines

Move the sys_timer definition out of ttc driver and make it part of the common zynq code. This is preparation for renaming and COMMON_CLK support.

---
 arch/arm/mach-zynq/common.c | 13 +++++++++++++
 arch/arm/mach-zynq/common.h |  4 +---
 arch/arm/mach-zynq/timer.c  | 10 +---------
 3 files changed, 15 insertions(+), 12 deletions(-)

Looks good to me. I have added it to my testing branch and will provide path to mainline through xilinx arm-next branch

Thanks,
Michal

#3 lore raw

PATCH 2/8 ARM: zynq: move ttc timer code to drivers/clocksource

In reply to Josh Cartwright

Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to drivers/clocksource, and out of the mach-zynq directory.

The common.h (which only held the timer declaration) was renamed to xilinx_ttc.h and moved into include/linux.

---
 arch/arm/mach-zynq/Makefile                                    | 2 +-
 arch/arm/mach-zynq/common.c                                    | 2 +-
 drivers/clocksource/Makefile                                   | 1 +
 arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
 arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h      | 4 ++--
 5 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
 rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
arch/arm/mach-zynq/Makefile +1 -1
index 397268c..320faed 100644
@@ -3,4 +3,4 @@
 #
 
 # Common support
-obj-y				:= common.o timer.o
+obj-y				:= common.o
arch/arm/mach-zynq/common.c +1 -1
index 6f058258..0279ea7 100644
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of.h>
+#include <linux/xilinx_ttc.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -32,7 +33,6 @@
 #include <asm/hardware/cache-l2x0.h>
 
 #include <mach/zynq_soc.h>
-#include "common.h"
 
 static struct of_device_id zynq_of_bus_ids[] __initdata = {
 	{ .compatible = "simple-bus", },
drivers/clocksource/Makefile +1 -0
index 603be36..f27c7b1 100644
@@ -14,5 +14,6 @@ obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
+obj-$(CONFIG_ARCH_ZYNQ)		+= xilinx_ttc.o
 
 obj-$(CONFIG_CLKSRC_ARM_GENERIC)	+= arm_generic.o
drivers/clocksource/xilinx_ttc.c renamed from arch/arm/mach-zynq/timer.c +0 -1
similarity index 99%
rename from arch/arm/mach-zynq/timer.c
rename to drivers/clocksource/xilinx_ttc.c
index c93cbe5..ff38b3e 100644
@@ -25,7 +25,6 @@
 #include <linux/io.h>
 
 #include <mach/zynq_soc.h>
-#include "common.h"
 
 #define IRQ_TIMERCOUNTER0	42
 
include/linux/xilinx_ttc.h renamed from arch/arm/mach-zynq/common.h +2 -2
similarity index 91%
rename from arch/arm/mach-zynq/common.h
rename to include/linux/xilinx_ttc.h
index 954b91c..303a3fd 100644
@@ -14,8 +14,8 @@
  * GNU General Public License for more details.
  */
 
-#ifndef __MACH_ZYNQ_COMMON_H__
-#define __MACH_ZYNQ_COMMON_H__
+#ifndef __XILINX_TTC_H__
+#define __XILINX_TTC_H__
 
 void __init xttcpss_timer_init(void);
 
Signature · 1 line
1.8.0
#4 lore raw

Re: [PATCH 2/8] ARM: zynq: move ttc timer code to drivers/clocksource

2012/10/29 Josh Cartwright <[email protected]>:

Quoted 8 lines

Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to drivers/clocksource, and out of the mach-zynq directory.

The common.h (which only held the timer declaration) was renamed to xilinx_ttc.h and moved into include/linux.

Quoted 9 lines
---
 arch/arm/mach-zynq/Makefile                                    | 2 +-
 arch/arm/mach-zynq/common.c                                    | 2 +-
 drivers/clocksource/Makefile                                   | 1 +
 arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
 arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h      | 4 ++--
 5 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
 rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)

Not going to apply this patch till there is clean way how to move all drivers there.
Especially I don't like to add xilinx_ttc.h to include/linux folder.

Thanks,
Michal

#5 lore raw

Re: [PATCH 2/8] ARM: zynq: move ttc timer code to drivers/clocksource

Quoted 19 lines · Michal Simek

2012/10/29 Josh Cartwright <[email protected]>:

Quoted 8 lines

Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to drivers/clocksource, and out of the mach-zynq directory.

The common.h (which only held the timer declaration) was renamed to xilinx_ttc.h and moved into include/linux.

Quoted 9 lines
---
 arch/arm/mach-zynq/Makefile                                    | 2 +-
 arch/arm/mach-zynq/common.c                                    | 2 +-
 drivers/clocksource/Makefile                                   | 1 +
 arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
 arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h      | 4 ++--
 5 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
 rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Quoted 4 lines

Not going to apply this patch till there is clean way how to move all drivers there.
Especially I don't like to add xilinx_ttc.h to include/linux folder.

A cleaner way is how we are doing irqchips [1]. This needs a single function (or one each for clksrc and clkevt) that has a DT match list of all known timers and calls their init function. It should be a bit simpler than irqchips init function because you don't need to worry about hierarchy init ordering. That doesn't solve non-DT though and if there are any extra functions like we have with irqchips, you still need the header in include/linux.

Rob

[1] http://www.spinics.net/lists/arm-kernel/msg203687.html

#6 lore raw

Re: [PATCH 2/8] ARM: zynq: move ttc timer code to drivers/clocksource

In reply to Michal Simek
Quoted 19 lines · Michal Simek

2012/10/29 Josh Cartwright <[email protected]>:

Quoted 8 lines

Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to drivers/clocksource, and out of the mach-zynq directory.

The common.h (which only held the timer declaration) was renamed to xilinx_ttc.h and moved into include/linux.

Quoted 9 lines
---
 arch/arm/mach-zynq/Makefile                                    | 2 +-
 arch/arm/mach-zynq/common.c                                    | 2 +-
 drivers/clocksource/Makefile                                   | 1 +
 arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
 arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h      | 4 ++--
 5 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
 rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Quoted 3 lines

Not going to apply this patch till there is clean way how to move all drivers there. Especially I don't like to add xilinx_ttc.h to include/linux folder.

Okay; I think it's best to defer the moving of the ttc driver from this patchset. It is not a dependency of the clk driver support stuff. If you agree, I can spin up a v2 of the patchset w/o this change, and without the serial CONFIG_OF stuff. Should v2 contain the patches you've already pulled into testing?

I'll give Rob's irqchip-like suggestion a spin and see how that works out in parallel.

Thanks,

Josh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121105/54a58e60/attachment.sig>

#7 lore raw

Re: [PATCH 2/8] ARM: zynq: move ttc timer code to drivers/clocksource

2012/11/5 Josh Cartwright <[email protected]>:

Quoted 24 lines · Michal Simek
Quoted 19 lines

2012/10/29 Josh Cartwright <[email protected]>:

Quoted 8 lines

Suggested cleanup by Arnd Bergmann. Move the ttc timer.c code to drivers/clocksource, and out of the mach-zynq directory.

The common.h (which only held the timer declaration) was renamed to xilinx_ttc.h and moved into include/linux.

Quoted 9 lines
---
 arch/arm/mach-zynq/Makefile                                    | 2 +-
 arch/arm/mach-zynq/common.c                                    | 2 +-
 drivers/clocksource/Makefile                                   | 1 +
 arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c | 1 -
 arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h      | 4 ++--
 5 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/mach-zynq/timer.c => drivers/clocksource/xilinx_ttc.c (99%)
 rename arch/arm/mach-zynq/common.h => include/linux/xilinx_ttc.h (91%)
Quoted 3 lines

Not going to apply this patch till there is clean way how to move all drivers there. Especially I don't like to add xilinx_ttc.h to include/linux folder.

Quoted 5 lines

Okay; I think it's best to defer the moving of the ttc driver from this patchset. It is not a dependency of the clk driver support stuff. If you agree, I can spin up a v2 of the patchset w/o this change, and without the serial CONFIG_OF stuff. Should v2 contain the patches you've already pulled into testing?

Sure and I see you have done which is good.

Thanks,
Michal

#8 lore raw

PATCH 3/8 ARM: zynq: dts: add description of the second uart

In reply to Josh Cartwright

The zynq-7000 has an additional UART at 0xE0001000. Describe it in the device tree.

---
 arch/arm/boot/dts/zynq-ep107.dts | 7 +++++++
 1 file changed, 7 insertions(+)
arch/arm/boot/dts/zynq-ep107.dts +7 -0
index 574bc04..5caf100 100644
@@ -59,5 +59,12 @@
 			interrupts = <0 27 4>;
 			clock = <50000000>;
 		};
+
+		uart1: uart at e0001000 {
+			compatible = "xlnx,xuartps";
+			reg = <0xE0001000 0x1000>;
+			interrupts = <0 50 4>;
+			clock = <50000000>;
+		};
 	};
 };
Signature · 1 line
1.8.0
#9 lore raw

Re: [PATCH 3/8] ARM: zynq: dts: add description of the second uart

2012/10/31 Josh Cartwright <[email protected]>:

Quoted 7 lines

The zynq-7000 has an additional UART at 0xE0001000. Describe it in the device tree.

---
 arch/arm/boot/dts/zynq-ep107.dts | 7 +++++++
 1 file changed, 7 insertions(+)

Applied to my testing branch.

Thanks,
Michal

#10 lore raw

PATCH 4/8 ARM: zynq: dts: split up device tree

In reply to Josh Cartwright

The purpose of the created zynq-7000.dtsi file is to describe the hardware common to all Zynq 7000-based boards. Also, get rid of the zynq-ep107 device tree, since it is not hardware anyone can purchase.

Add a zc702 dts file based on the zynq-7000.dtsi. Add it to the dts/Makefile so it is built with the 'dtbs' target.

---
 arch/arm/boot/dts/Makefile                         |  1 +
 .../boot/dts/{zynq-ep107.dts => zynq-7000.dtsi}    | 19 +++-----------
 arch/arm/boot/dts/zynq-zc702.dts                   | 30 ++++++++++++++++++++++
 arch/arm/mach-zynq/common.c                        |  3 ++-
 4 files changed, 36 insertions(+), 17 deletions(-)
 rename arch/arm/boot/dts/{zynq-ep107.dts => zynq-7000.dtsi} (79%)
 create mode 100644 arch/arm/boot/dts/zynq-zc702.dts
arch/arm/boot/dts/Makefile +1 -0
index f37cf9f..76ed11e 100644
@@ -103,5 +103,6 @@ dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
 dtb-$(CONFIG_ARCH_VT8500) += vt8500-bv07.dtb \
 	wm8505-ref.dtb \
 	wm8650-mid.dtb
+dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb
 
 endif
arch/arm/boot/dts/zynq-7000.dtsi renamed from arch/arm/boot/dts/zynq-ep107.dts +3 -16
similarity index 79%
rename from arch/arm/boot/dts/zynq-ep107.dts
rename to arch/arm/boot/dts/zynq-7000.dtsi
index 5caf100..8b30e59 100644
@@ -10,29 +10,16 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+/include/ "skeleton.dtsi"
 
-/dts-v1/;
 / {
-	model = "Xilinx Zynq EP107";
-	compatible = "xlnx,zynq-ep107";
-	#address-cells = <1>;
-	#size-cells = <1>;
-	interrupt-parent = <&intc>;
-
-	memory {
-		device_type = "memory";
-		reg = <0x0 0x10000000>;
-	};
-
-	chosen {
-		bootargs = "console=ttyPS0,9600 root=/dev/ram rw initrd=0x800000,8M earlyprintk";
-		linux,stdout-path = &uart0;
-	};
+	compatible = "xlnx,zynq-7000";
 
 	amba {
 		compatible = "simple-bus";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		interrupt-parent = <&intc>;
 		ranges;
 
 		intc: interrupt-controller at f8f01000 {
arch/arm/boot/dts/zynq-zc702.dts new file +30 -0
new file mode 100644
index 0000000..e25a307
@@ -0,0 +1,30 @@
+/*
+ *  Copyright (C) 2011 Xilinx
+ *  Copyright (C) 2012 National Instruments Corp.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+/dts-v1/;
+/include/ "zynq-7000.dtsi"
+
+/ {
+	model = "Zynq ZC702 Development Board";
+	compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyPS1,115200 earlyprintk";
+	};
+
+};
arch/arm/mach-zynq/common.c +2 -1
index 0279ea7..447904b 100644
@@ -115,7 +115,8 @@ static void __init xilinx_map_io(void)
 }
 
 static const char *xilinx_dt_match[] = {
-	"xlnx,zynq-ep107",
+	"xlnx,zynq-zc702",
+	"xlnx,zynq-7000",
 	NULL
 };
 
Signature · 1 line
1.8.0
#11 lore raw

Re: [PATCH 4/8] ARM: zynq: dts: split up device tree

2012/10/31 Josh Cartwright <[email protected]>:

Quoted 8 lines

The purpose of the created zynq-7000.dtsi file is to describe the hardware common to all Zynq 7000-based boards. Also, get rid of the zynq-ep107 device tree, since it is not hardware anyone can purchase.

Add a zc702 dts file based on the zynq-7000.dtsi. Add it to the dts/Makefile so it is built with the 'dtbs' target.

Quoted 8 lines
---
 arch/arm/boot/dts/Makefile                         |  1 +
 .../boot/dts/{zynq-ep107.dts => zynq-7000.dtsi}    | 19 +++-----------
 arch/arm/boot/dts/zynq-zc702.dts                   | 30 ++++++++++++++++++++++
 arch/arm/mach-zynq/common.c                        |  3 ++-
 4 files changed, 36 insertions(+), 17 deletions(-)
 rename arch/arm/boot/dts/{zynq-ep107.dts => zynq-7000.dtsi} (79%)
 create mode 100644 arch/arm/boot/dts/zynq-zc702.dts

Not going to apply this. We need to finish our discussion in "[PATCH v4 1/5] zynq: use GIC device tree bindings" before.

Definitely I like idea to use "xlnx,zynq-7000" generic model name.

Thanks,
Michal

#12 lore raw

PATCH 5/8 ARM: zynq: add COMMON_CLK support

In reply to Josh Cartwright

Add support for COMMON_CLK, and provide simplified models for the necessary clocks on the zynq-7000. Currently, the PLLs, the CPU clock network, and the basic peripheral clock networks (for SDIO, SMC, SPI, QSPI, UART) are modelled.

---
 .../devicetree/bindings/clock/zynq-7000.txt        |  55 ++++
 arch/arm/Kconfig                                   |   1 +
 arch/arm/boot/dts/zynq-7000.dtsi                   |  56 ++++
 arch/arm/boot/dts/zynq-zc702.dts                   |   4 +
 arch/arm/mach-zynq/common.c                        |  11 +
 drivers/clk/Makefile                               |   1 +
 drivers/clk/clk-zynq.c                             | 355 +++++++++++++++++++++
 include/linux/clk/zynq.h                           |  24 ++
 8 files changed, 507 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/zynq-7000.txt
 create mode 100644 drivers/clk/clk-zynq.c
 create mode 100644 include/linux/clk/zynq.h
Documentation/devicetree/bindings/clock/zynq-7000.txt new file +55 -0
new file mode 100644
index 0000000..2e21fc1
@@ -0,0 +1,55 @@
+Device Tree Clock bindings for the Zynq 7000 EPP
+
+The Zynq EPP has several different clk providers, each with there own bindings.
+The purpose of this document is to document their usage.
+
+See clock_bindings.txt for more information on the generic clock bindings.
+See Chapter 25 of Zynq TRM for more information about Zynq clocks.
+
+== PLLs ==
+
+Used to describe the ARM_PLL, DDR_PLL, and IO_PLL.
+
+Required properties:
+- #clock-cells : shall be 0 (only one clock is output from this node)
+- compatible : "xlnx,zynq-pll"
+- reg : pair of u32 values, which are the address offsets within the SLCR
+        of the relevant PLL_CTRL register and PLL_CFG register respectively
+- clocks : phandle for parent clock.  should be the phandle for ps_clk
+
+Optional properties:
+- clock-output-names : name of the output clock
+
+Example:
+	armpll: armpll {
+		#clock-cells = <0>;
+		compatible = "xlnx,zynq-pll";
+		clocks = <&ps_clk>;
+		reg = <0x100 0x110>;
+		clock-output-names = "armpll";
+	};
+
+== Peripheral clocks ==
+
+Describes clock node for the SDIO, SMC, SPI, QSPI, and UART clocks.
+
+Required properties:
+- #clock-cells : shall be 1
+- compatible : "xlnx,zynq-periph-clock"
+- reg : a single u32 value, describing the offset within the SLCR where
+        the CLK_CTRL register is found for this peripheral
+- clocks : phandle for parent clocks.  should hold phandles for
+           the IO_PLL, ARM_PLL, and DDR_PLL in order
+
+Optional properties:
+- clock-output-names : name of the output clock
+
+Example:
+	uart_clk: uart_clk {
+		#clock-cells = <1>;
+		compatible = "xlnx,zynq-periph-clock";
+		clocks = <&iopll &armpll &ddrpll>;
+		reg = <0x154>;
+		clock-output-names = "uart0_ref_clk",
+				     "uart1_ref_clk";
+	};
arch/arm/Kconfig +1 -0
index 21ed87b..ccfe0ab 100644
@@ -959,6 +959,7 @@ config ARCH_ZYNQ
 	bool "Xilinx Zynq ARM Cortex A9 Platform"
 	select ARM_AMBA
 	select ARM_GIC
+	select COMMON_CLK
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select ICST
arch/arm/boot/dts/zynq-7000.dtsi +56 -0

61 lines not on this page · raw message

arch/arm/boot/dts/zynq-zc702.dts +4 -0
index e25a307..86f44d5 100644
@@ -28,3 +28,7 @@
 	};
 
 };
+
+&ps_clk {
+	clock-frequency = <33333330>;
+};
arch/arm/mach-zynq/common.c +11 -0
index 447904b..f0cb3e4 100644
@@ -19,6 +19,8 @@
 #include <linux/cpumask.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/clk/zynq.h>
+#include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/of.h>
@@ -96,6 +98,15 @@ static struct map_desc io_desc[] __initdata = {
 
 static void __init xilinx_zynq_timer_init(void)
 {
+	struct device_node *np;
+	void __iomem *slcr;
+
+	np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-slcr");
+	slcr = of_iomap(np, 0);
+	WARN_ON(!slcr);
+
+	xilinx_zynq_clocks_init(slcr);
+
 	xttcpss_timer_init();
 }
 
drivers/clk/Makefile +1 -0
index 71a25b9..d35a34c 100644
@@ -19,6 +19,7 @@ endif
 obj-$(CONFIG_MACH_LOONGSON1)	+= clk-ls1x.o
 obj-$(CONFIG_ARCH_U8500)	+= ux500/
 obj-$(CONFIG_ARCH_VT8500)	+= clk-vt8500.o
+obj-$(CONFIG_ARCH_ZYNQ)		+= clk-zynq.o
 
 # Chip specific
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
drivers/clk/clk-zynq.c new file +355 -0

355 lines not on this page · raw message

include/linux/clk/zynq.h new file +24 -0
new file mode 100644
index 0000000..56be7cd
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 National Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __LINUX_CLK_ZYNQ_H_
+#define __LINUX_CLK_ZYNQ_H_
+
+void __init xilinx_zynq_clocks_init(void __iomem *slcr);
+
+#endif
Signature · 1 line
1.8.0
#13 lore raw

Re: [PATCH 5/8] ARM: zynq: add COMMON_CLK support

drivers/clk/clk-zynq.c line 95

Quoted 3 lines · Josh Cartwright

[...]

drivers/clk/clk-zynq.c new file +2 -0
+#define PERIPH_CLK_CTRL_SRC(x)	(periph_clk_parent_map[((x)&3)>>4])
+#define PERIPH_CLK_CTRL_DIV(x)	(((x)&0x3F00)>>8)

A few more spaces wouldn't hurt ;)

drivers/clk/clk-zynq.c line 126

Quoted 13 lines

[...]

drivers/clk/clk-zynq.c new file +12 -0
+static void __init zynq_periph_clk_setup(struct device_node *np)
+{
+	struct zynq_periph_clk *periph;
+	const char *parent_names[3];
+	struct clk_init_data init;
+	struct clk *clk;
+	int err;
+	u32 reg;
+	int i;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	WARN_ON(err);

Shouldn't the function abort if a error happens somewhere? Continuing here will lead to undefined behavior. Same is probably true for the other WARN_ONs.

Quoted 13 lines
drivers/clk/clk-zynq.c new file +13 -0
+
+	periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+	WARN_ON(!periph);
+
+	periph->clk_ctrl = slcr_base + reg;
+	spin_lock_init(&periph->clkact_lock);
+
+	init.name = np->name;
+	init.ops = &zynq_periph_clk_ops;
+	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+	init.parent_names = parent_names;
+	init.num_parents = ARRAY_SIZE(parent_names);

drivers/clk/clk-zynq.c line 149

Quoted 10 lines
drivers/clk/clk-zynq.c new file +10 -0
+
+	periph->hw.init = &init;
+
+	clk = clk_register(NULL, &periph->hw);
+	WARN_ON(IS_ERR(clk));
+
+	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	WARN_ON(err);
+
+	for (i = 0; i < 2; i++) {

Not all of the peripheral clock generators have two output clocks. I think it makes sense to use the number entries in clock-output-names here.

Quoted 20 lines
drivers/clk/clk-zynq.c new file +19 -0
+		const char *name;
+
+		err = of_property_read_string_index(np, "clock-output-names", i,
+						    &name);
+		WARN_ON(err);
+
+		periph->gates[i] = clk_register_gate(NULL, name, np->name, 0,
+						     periph->clk_ctrl, i, 0,
+						     &periph->clkact_lock);
+		WARN_ON(IS_ERR(periph->gates[i]));
+	}
+
+	periph->onecell_data.clks = periph->gates;
+	periph->onecell_data.clk_num = i;
+
+	err = of_clk_add_provider(np, of_clk_src_onecell_get,
+				  &periph->onecell_data);
+	WARN_ON(err);
+}
[...]
#14 lore raw

Re: [PATCH 5/8] ARM: zynq: add COMMON_CLK support

Thanks for the review.

Quoted 6 lines · Lars-Peter Clausen

drivers/clk/clk-zynq.c line 95

Quoted 3 lines · Josh Cartwright

[...]

drivers/clk/clk-zynq.c new file +2 -0
+#define PERIPH_CLK_CTRL_SRC(x)	(periph_clk_parent_map[((x)&3)>>4])
+#define PERIPH_CLK_CTRL_DIV(x)	(((x)&0x3F00)>>8)

A few more spaces wouldn't hurt ;)

Okay, sure.

Quoted 8 lines
Quoted 8 lines

[...]

drivers/clk/clk-zynq.c new file +7 -0
+static void __init zynq_periph_clk_setup(struct device_node *np)
+{
+	struct zynq_periph_clk *periph;
+	const char *parent_names[3];
+	struct clk_init_data init;
+	struct clk *clk;
+	int err;
Quoted 8 lines

drivers/clk/clk-zynq.c line 126

Quoted 5 lines
drivers/clk/clk-zynq.c new file +5 -0
+	u32 reg;
+	int i;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	WARN_ON(err);

Shouldn't the function abort if a error happens somewhere? Continuing here will lead to undefined behavior. Same is probably true for the other WARN_ONs.

The way I see it is: the kernel is will be left in a bad state in the case of any failure, regardless of if we bail out or continue. AFAICT, there is no clean way to recover from a failure this early.

Given that, it seems simpler (albeit marginally so) just to continue; so that's what I chose to do. I'm not opposed to bailing out, just not convinced it does anything for us.

Quoted 18 lines
Quoted 18 lines
drivers/clk/clk-zynq.c new file +18 -0
+
+	periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+	WARN_ON(!periph);
+
+	periph->clk_ctrl = slcr_base + reg;
+	spin_lock_init(&periph->clkact_lock);
+
+	init.name = np->name;
+	init.ops = &zynq_periph_clk_ops;
+	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+	init.parent_names = parent_names;
+	init.num_parents = ARRAY_SIZE(parent_names);
+
+	periph->hw.init = &init;
+
+	clk = clk_register(NULL, &periph->hw);
+	WARN_ON(IS_ERR(clk));
Quoted 8 lines

drivers/clk/clk-zynq.c line 149

Quoted 5 lines
drivers/clk/clk-zynq.c new file +5 -0
+
+	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	WARN_ON(err);
+
+	for (i = 0; i < 2; i++) {

Not all of the peripheral clock generators have two output clocks. I think it makes sense to use the number entries in clock-output-names here.

Yes, I agree. I'll also update the bindings documentation.

Thanks again,
Josh

#15 lore raw

Re: [PATCH 5/8] ARM: zynq: add COMMON_CLK support

Quoted 29 lines · Josh Cartwright

Thanks for the review.

Quoted 6 lines · Lars-Peter Clausen

drivers/clk/clk-zynq.c line 95

Quoted 3 lines · Josh Cartwright

[...]

drivers/clk/clk-zynq.c new file +2 -0
+#define PERIPH_CLK_CTRL_SRC(x)	(periph_clk_parent_map[((x)&3)>>4])
+#define PERIPH_CLK_CTRL_DIV(x)	(((x)&0x3F00)>>8)

A few more spaces wouldn't hurt ;)

Okay, sure.

Quoted 8 lines
Quoted 8 lines

[...]

drivers/clk/clk-zynq.c new file +7 -0
+static void __init zynq_periph_clk_setup(struct device_node *np)
+{
+	struct zynq_periph_clk *periph;
+	const char *parent_names[3];
+	struct clk_init_data init;
+	struct clk *clk;
+	int err;
Quoted 8 lines

drivers/clk/clk-zynq.c line 126

Quoted 5 lines
drivers/clk/clk-zynq.c new file +5 -0
+	u32 reg;
+	int i;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	WARN_ON(err);

Shouldn't the function abort if a error happens somewhere? Continuing here will lead to undefined behavior. Same is probably true for the other WARN_ONs.

Quoted 8 lines

The way I see it is: the kernel is will be left in a bad state in the case of any failure, regardless of if we bail out or continue. AFAICT, there is no clean way to recover from a failure this early.

Given that, it seems simpler (albeit marginally so) just to continue; so that's what I chose to do. I'm not opposed to bailing out, just not convinced it does anything for us.

The issue with this approach is that, while you get a warning, unexpected seemingly unrelated side-effects may happen later on. E.g. if no reg property for the clock is specified the reg variable will be uninitialized and contain whatever was on the stack before. The clock will be registered nonetheless and the boot process continues. Now if the clock is enabled a bit in a random register will be modified, which could result in strange and abnormal behavior, which can be very hard to track down.

Also if for example just one clock has its reg property missing the system will continue to boot if we bail out here. It is just that the peripherals using that clock won't work. Which will certainly be easier to diagnose than random abnormal behavior.

Quoted 31 lines
Quoted 18 lines
Quoted 18 lines
drivers/clk/clk-zynq.c new file +18 -0
+
+	periph = kzalloc(sizeof(*periph), GFP_KERNEL);
+	WARN_ON(!periph);
+
+	periph->clk_ctrl = slcr_base + reg;
+	spin_lock_init(&periph->clkact_lock);
+
+	init.name = np->name;
+	init.ops = &zynq_periph_clk_ops;
+	for (i = 0; i < ARRAY_SIZE(parent_names); i++)
+		parent_names[i] = of_clk_get_parent_name(np, i);
+	init.parent_names = parent_names;
+	init.num_parents = ARRAY_SIZE(parent_names);
+
+	periph->hw.init = &init;
+
+	clk = clk_register(NULL, &periph->hw);
+	WARN_ON(IS_ERR(clk));
Quoted 8 lines

drivers/clk/clk-zynq.c line 149

Quoted 5 lines
drivers/clk/clk-zynq.c new file +5 -0
+
+	err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	WARN_ON(err);
+
+	for (i = 0; i < 2; i++) {

Not all of the peripheral clock generators have two output clocks. I think it makes sense to use the number entries in clock-output-names here.

Yes, I agree. I'll also update the bindings documentation.

Thanks again,
Josh

#16 lore raw

Re: [PATCH 5/8] ARM: zynq: add COMMON_CLK support

Quoted 3 lines · Lars-Peter Clausen
Quoted 2 lines · Josh Cartwright
Quoted 1 line · Lars-Peter Clausen

On 10/31/2012 07:58 PM, Josh Cartwright wrote:

[...]

Quoted 24 lines
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
drivers/clk/clk-zynq.c new file +7 -0
+static void __init zynq_periph_clk_setup(struct device_node *np)
+{
+	struct zynq_periph_clk *periph;
+	const char *parent_names[3];
+	struct clk_init_data init;
+	struct clk *clk;
+	int err;
Quoted 8 lines

drivers/clk/clk-zynq.c line 126

Quoted 5 lines
drivers/clk/clk-zynq.c new file +5 -0
+	u32 reg;
+	int i;
+
+	err = of_property_read_u32(np, "reg", &reg);
+	WARN_ON(err);

Shouldn't the function abort if a error happens somewhere? Continuing here will lead to undefined behavior. Same is probably true for the other WARN_ONs.

Quoted 8 lines

The way I see it is: the kernel is will be left in a bad state in the case of any failure, regardless of if we bail out or continue. AFAICT, there is no clean way to recover from a failure this early.

Given that, it seems simpler (albeit marginally so) just to continue; so that's what I chose to do. I'm not opposed to bailing out, just not convinced it does anything for us.

Quoted 7 lines

The issue with this approach is that, while you get a warning, unexpected seemingly unrelated side-effects may happen later on. E.g. if no reg property for the clock is specified the reg variable will be uninitialized and contain whatever was on the stack before. The clock will be registered nonetheless and the boot process continues. Now if the clock is enabled a bit in a random register will be modified, which could result in strange and abnormal behavior, which can be very hard to track down.

Okay.....but any reasonable person would start their debugging quest at the source of the WARN_ON. If someone sees the WARN_ON message but stupidly chooses to ignore it, they deserves to spend the time trying to track down abnormal behavior, so I'm still not convinced.

Josh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121102/4744adbf/attachment.sig>

#17 lore raw

Re: [PATCH 5/8] ARM: zynq: add COMMON_CLK support

2012/11/2 Josh Cartwright <[email protected]>:

Quoted 37 lines · Lars-Peter Clausen
Quoted 3 lines · Josh Cartwright
Quoted 2 lines · Lars-Peter Clausen
Quoted 1 line · Josh Cartwright

[...]

Quoted 24 lines
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
drivers/clk/clk-zynq.c new file +7 -0
+static void __init zynq_periph_clk_setup(struct device_node *np)
+{
+ struct zynq_periph_clk *periph;
+ const char *parent_names[3];
+ struct clk_init_data init;
+ struct clk *clk;
+ int err;
Quoted 8 lines
Quoted 5 lines

+ u32 reg;
+ int i;
+
+ err = of_property_read_u32(np, "reg", &reg);
+ WARN_ON(err);

Shouldn't the function abort if a error happens somewhere? Continuing here will lead to undefined behavior. Same is probably true for the other WARN_ONs.

Quoted 8 lines

The way I see it is: the kernel is will be left in a bad state in the case of any failure, regardless of if we bail out or continue. AFAICT, there is no clean way to recover from a failure this early.

Given that, it seems simpler (albeit marginally so) just to continue; so that's what I chose to do. I'm not opposed to bailing out, just not convinced it does anything for us.

Quoted 7 lines

The issue with this approach is that, while you get a warning, unexpected seemingly unrelated side-effects may happen later on. E.g. if no reg property for the clock is specified the reg variable will be uninitialized and contain whatever was on the stack before. The clock will be registered nonetheless and the boot process continues. Now if the clock is enabled a bit in a random register will be modified, which could result in strange and abnormal behavior, which can be very hard to track down.

Quoted 4 lines

Okay.....but any reasonable person would start their debugging quest at the source of the WARN_ON. If someone sees the WARN_ON message but stupidly chooses to ignore it, they deserves to spend the time trying to track down abnormal behavior, so I'm still not convinced.

I am with Lars. You would be surprised how many people do no read bootlog. It should be handled better.

Thanks,
Michal

#18 lore raw

PATCH 6/8 serial: xilinx_uartps: kill CONFIG_OF conditional

In reply to Josh Cartwright

The Zynq platform requires the use of CONFIG_OF. Remove the #ifdef conditionals in the uartps driver.

---
 drivers/tty/serial/xilinx_uartps.c | 9 ---------
 1 file changed, 9 deletions(-)
drivers/tty/serial/xilinx_uartps.c +0 -9
index b627363..23efe17 100644
@@ -946,15 +946,11 @@ static int __devinit xuartps_probe(struct platform_device *pdev)
 	struct resource *res, *res2;
 	int clk = 0;
 
-#ifdef CONFIG_OF
 	const unsigned int *prop;
 
 	prop = of_get_property(pdev->dev.of_node, "clock", NULL);
 	if (prop)
 		clk = be32_to_cpup(prop);
-#else
-	clk = *((unsigned int *)(pdev->dev.platform_data));
-#endif
 	if (!clk) {
 		dev_err(&pdev->dev, "no clock specified\n");
 		return -ENODEV;
@@ -1044,16 +1040,11 @@ static int xuartps_resume(struct platform_device *pdev)
 }
 
 /* Match table for of_platform binding */
-
-#ifdef CONFIG_OF
 static struct of_device_id xuartps_of_match[] __devinitdata = {
 	{ .compatible = "xlnx,xuartps", },
 	{}
 };
 MODULE_DEVICE_TABLE(of, xuartps_of_match);
-#else
-#define xuartps_of_match NULL
-#endif
 
 static struct platform_driver xuartps_platform_driver = {
 	.probe   = xuartps_probe,		/* Probe method */
Signature · 1 line
1.8.0
#19 lore raw

Re: [PATCH 6/8] serial: xilinx_uartps: kill CONFIG_OF conditional

2012/10/30 Josh Cartwright <[email protected]>:

Quoted 7 lines

The Zynq platform requires the use of CONFIG_OF. Remove the #ifdef conditionals in the uartps driver.

---
 drivers/tty/serial/xilinx_uartps.c | 9 ---------
 1 file changed, 9 deletions(-)

Please send this separately out of this patchset.
Also if you do this change which is understandable, you should also add
depends on OF

Thanks,
Michal

#20 lore raw

PATCH 7/8 serial: xilinx_uartps: get clock rate info from dts

In reply to Josh Cartwright

Add support for specifying clock information for the uart clk via the device tree. This eliminates the need to hardcode rates in the device tree.

---
 arch/arm/boot/dts/zynq-7000.dtsi   |  4 ++--
 drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++-------------
 2 files changed, 19 insertions(+), 15 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +2 -2
index bb3085c..5fb763f 100644
@@ -44,14 +44,14 @@
 			compatible = "xlnx,xuartps";
 			reg = <0xE0000000 0x1000>;
 			interrupts = <0 27 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;
 		};
 
 		uart1: uart at e0001000 {
 			compatible = "xlnx,xuartps";
 			reg = <0xE0001000 0x1000>;
 			interrupts = <0 50 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;
 		};
 
 		slcr: slcr at f8000000 {
drivers/tty/serial/xilinx_uartps.c +17 -13
index 23efe17..adfecbc 100644
@@ -17,6 +17,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/console.h>
+#include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -944,18 +945,20 @@ static int __devinit xuartps_probe(struct platform_device *pdev)
 	int rc;
 	struct uart_port *port;
 	struct resource *res, *res2;
-	int clk = 0;
+	struct clk *clk;
 
-	const unsigned int *prop;
-
-	prop = of_get_property(pdev->dev.of_node, "clock", NULL);
-	if (prop)
-		clk = be32_to_cpup(prop);
+	clk = of_clk_get(pdev->dev.of_node, 0);
 	if (!clk) {
 		dev_err(&pdev->dev, "no clock specified\n");
 		return -ENODEV;
 	}
 
+	rc = clk_prepare_enable(clk);
+	if (rc) {
+		dev_err(&pdev->dev, "could not enable clock\n");
+		return -EBUSY;
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
@@ -978,7 +981,8 @@ static int __devinit xuartps_probe(struct platform_device *pdev)
 		port->mapbase = res->start;
 		port->irq = res2->start;
 		port->dev = &pdev->dev;
-		port->uartclk = clk;
+		port->uartclk = clk_get_rate(clk);
+		port->private_data = clk;
 		dev_set_drvdata(&pdev->dev, port);
 		rc = uart_add_one_port(&xuartps_uart_driver, port);
 		if (rc) {
@@ -1000,14 +1004,14 @@ static int __devinit xuartps_probe(struct platform_device *pdev)
 static int __devexit xuartps_remove(struct platform_device *pdev)
 {
 	struct uart_port *port = dev_get_drvdata(&pdev->dev);
-	int rc = 0;
+	struct clk *clk = port->private_data;
+	int rc;
 
 	/* Remove the xuartps port from the serial core */
-	if (port) {
-		rc = uart_remove_one_port(&xuartps_uart_driver, port);
-		dev_set_drvdata(&pdev->dev, NULL);
-		port->mapbase = 0;
-	}
+	rc = uart_remove_one_port(&xuartps_uart_driver, port);
+	dev_set_drvdata(&pdev->dev, NULL);
+	port->mapbase = 0;
+	clk_disable_unprepare(clk);
 	return rc;
 }
 
Signature · 1 line
1.8.0
#21 lore raw

Re: [PATCH 7/8] serial: xilinx_uartps: get clock rate info from dts

Quoted 18 lines · Josh Cartwright

Add support for specifying clock information for the uart clk via the device tree. This eliminates the need to hardcode rates in the device tree.

---
 arch/arm/boot/dts/zynq-7000.dtsi   |  4 ++--
 drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++-------------
 2 files changed, 19 insertions(+), 15 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +0 -0
index bb3085c..5fb763f 100644
@@ -44,14 +44,14 @@
 			compatible = "xlnx,xuartps";
 			reg = <0xE0000000 0x1000>;
 			interrupts = <0 27 4>;

arch/arm/boot/dts/zynq-7000.dtsi line 54

Quoted 10 lines
arch/arm/boot/dts/zynq-7000.dtsi +2 -2
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;
 		};
 
 		uart1: uart at e0001000 {
 			compatible = "xlnx,xuartps";
 			reg = <0xE0001000 0x1000>;
 			interrupts = <0 50 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;

Shouldn't this be <&uart_clk 1>?

Quoted 3 lines
arch/arm/boot/dts/zynq-7000.dtsi +0 -0
 		};
 
 		slcr: slcr at f8000000 {
#22 lore raw

Re: [PATCH 7/8] serial: xilinx_uartps: get clock rate info from dts

Quoted 23 lines · Lars-Peter Clausen
Quoted 22 lines · Josh Cartwright

Add support for specifying clock information for the uart clk via the device tree. This eliminates the need to hardcode rates in the device tree.

---
 arch/arm/boot/dts/zynq-7000.dtsi   |  4 ++--
 drivers/tty/serial/xilinx_uartps.c | 30 +++++++++++++++++-------------
 2 files changed, 19 insertions(+), 15 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +1 -1
index bb3085c..5fb763f 100644
@@ -44,14 +44,14 @@
 			compatible = "xlnx,xuartps";
 			reg = <0xE0000000 0x1000>;
 			interrupts = <0 27 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;
 		};
 
Quoted 8 lines

arch/arm/boot/dts/zynq-7000.dtsi line 54

Quoted 6 lines
arch/arm/boot/dts/zynq-7000.dtsi +1 -1
 		uart1: uart at e0001000 {
 			compatible = "xlnx,xuartps";
 			reg = <0xE0001000 0x1000>;
 			interrupts = <0 50 4>;
-			clock = <50000000>;
+			clocks = <&uart_clk 0>;

Shouldn't this be <&uart_clk 1>?

Yes, indeed.

Thanks,
Josh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121102/a37426c2/attachment.sig>

#23 lore raw

PATCH 8/8 clocksource: xilinx_ttc: add OF_CLK support

In reply to Josh Cartwright

Add support for retrieving TTC configuration from device tree. This includes the ability to pull information about the driving clocks from the of_clk bindings.

---
 arch/arm/boot/dts/zynq-7000.dtsi |  53 ++++++++
 arch/arm/boot/dts/zynq-zc702.dts |  10 ++
 drivers/clocksource/xilinx_ttc.c | 273 ++++++++++++++++++++++-----------------
 3 files changed, 218 insertions(+), 118 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +53 -0
index 5fb763f..9a2442c 100644
@@ -109,5 +109,58 @@
 				};
 			};
 		};
+
+		ttc0: ttc0 at f8001000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "xlnx,ttc";
+			reg = <0xF8001000 0x1000>;
+			clocks = <&cpu_clk 3>;
+			clock-names = "cpu_1x";
+			clock-ranges;
+
+			ttc0_0: ttc0.0 {
+				status = "disabled";
+				reg = <0>;
+				interrupts = <0 10 4>;
+			};
+			ttc0_1: ttc0.1 {
+				status = "disabled";
+				reg = <1>;
+				interrupts = <0 11 4>;
+			};
+			ttc0_2: ttc0.2 {
+				status = "disabled";
+				reg = <2>;
+				interrupts = <0 12 4>;
+			};
+		};
+
+		ttc1: ttc0 at f8002000 {
+			#interrupt-parent = <&intc>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "xlnx,ttc";
+			reg = <0xF8002000 0x1000>;
+			clocks = <&cpu_clk 3>;
+			clock-names = "cpu_1x";
+			clock-ranges;
+
+			ttc1_0: ttc1.0 {
+				status = "disabled";
+				reg = <0>;
+				interrupts = <0 37 4>;
+			};
+			ttc1_1: ttc1.1 {
+				status = "disabled";
+				reg = <1>;
+				interrupts = <0 38 4>;
+			};
+			ttc1_2: ttc1.2 {
+				status = "disabled";
+				reg = <2>;
+				interrupts = <0 39 4>;
+			};
+		};
 	};
 };
arch/arm/boot/dts/zynq-zc702.dts +10 -0
index 86f44d5..c772942 100644
@@ -32,3 +32,13 @@
 &ps_clk {
 	clock-frequency = <33333330>;
 };
+
+&ttc0_0 {
+	status = "ok";
+	compatible = "xlnx,ttc-counter-clocksource";
+};
+
+&ttc0_1 {
+	status = "ok";
+	compatible = "xlnx,ttc-counter-clockevent";
+};
drivers/clocksource/xilinx_ttc.c +155 -118

357 lines not on this page · raw message

Signature · 1 line
1.8.0
#24 lore raw

Re: [PATCH 8/8] clocksource: xilinx_ttc: add OF_CLK support

Quoted 24 lines · Josh Cartwright

Add support for retrieving TTC configuration from device tree. This includes the ability to pull information about the driving clocks from the of_clk bindings.

---

drivers/clocksource/xilinx_ttc.c +2 -1
index ff38b3e..a4718f7 100644
@@ -209,7 +153,8 @@ static struct clocksource clocksource_xttcpss = {
 static int xttcpss_set_next_event(unsigned long cycles,
 					struct clock_event_device *evt)
 {
-	struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
+	struct xttcpss_timer_clockevent *xttce = to_xttcpss_timer_clkevent(evt);
+	struct xttcpss_timer *timer = &xttce->xttc;
 
 	xttcpss_set_interval(timer, cycles);
 	return 0;
@@ -224,12 +169,14 @@ static int xttcpss_set_next_event(unsigned long cycles,
 static void xttcpss_set_mode(enum clock_event_mode mode,
 					struct clock_event_device *evt)
 {

drivers/clocksource/xilinx_ttc.c static int xttcpss_set_next_event(unsigned long cycles, · line 179

Quoted 10 lines
drivers/clocksource/xilinx_ttc.c +4 -2
-	struct xttcpss_timer *timer = &timers[XTTCPSS_CLOCKEVENT];
+	struct xttcpss_timer_clockevent *xttce = to_xttcpss_timer_clkevent(evt);
+	struct xttcpss_timer *timer = &xttce->xttc;
 	u32 ctrl_reg;
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		xttcpss_set_interval(timer, TIMER_RATE / HZ);
+		xttcpss_set_interval(timer,
+				     clk_get_rate(xttce->clk) / PRESCALE);

I discovered with further testing that the above calculation is broken; calculated interval also needs to be divided by HZ.

(I'll post a v2; just wanted to get this out there in the slim chance anyone's testing this ;)

Josh

#25 lore raw

Re: [PATCH 8/8] clocksource: xilinx_ttc: add OF_CLK support

In reply to Josh Cartwright

2012/10/31 Josh Cartwright <[email protected]>:

Quoted 37 lines

Add support for retrieving TTC configuration from device tree. This includes the ability to pull information about the driving clocks from the of_clk bindings.

---
 arch/arm/boot/dts/zynq-7000.dtsi |  53 ++++++++
 arch/arm/boot/dts/zynq-zc702.dts |  10 ++
 drivers/clocksource/xilinx_ttc.c | 273 ++++++++++++++++++++++-----------------
 3 files changed, 218 insertions(+), 118 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +18 -0
index 5fb763f..9a2442c 100644
@@ -109,5 +109,58 @@
                                };
                        };
                };
+
+               ttc0: ttc0 at f8001000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "xlnx,ttc";
+                       reg = <0xF8001000 0x1000>;
+                       clocks = <&cpu_clk 3>;
+                       clock-names = "cpu_1x";
+                       clock-ranges;
+
+                       ttc0_0: ttc0.0 {
+                               status = "disabled";
+                               reg = <0>;
+                               interrupts = <0 10 4>;
+                       };
+                       ttc0_1: ttc0.1 {
+                               status = "disabled";
+                               reg = <1>;

arch/arm/boot/dts/zynq-7000.dtsi line 139

Quoted 10 lines
arch/arm/boot/dts/zynq-7000.dtsi +10 -0
+                               interrupts = <0 11 4>;
+                       };
+                       ttc0_2: ttc0.2 {
+                               status = "disabled";
+                               reg = <2>;
+                               interrupts = <0 12 4>;
+                       };
+               };
+
+               ttc1: ttc0 at f8002000 {

Also this is ttc1: ttc1.
These type of faults can be simple removed by proper dts node generation.

Thanks,
Michal

Signature · 4 lines
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian