Xilinx Zynq SLCR changes
Subsystems (5)
cover Xilinx Zynq SLCR changes
Hi,
I have rebased and added together patches I have got from Steffen some time ago.
Steffen: I kept there your SoB. Please let me know if there is any problem with it.
The point of this series is to use slcr as system controller to be able to create other drivers like pinmux, etc.
These patches are based on zynq/cleanup and zynq/dt branches merged together. (They are available in arm-soc git tree).
Let me know if you want to add the branch somewhere.
Arnd: We talked at KS about syscon early initialization which will be really helpful for this case. Has someone done any work around it?
Thanks,
Michal
Michal Simek (4):
ARM: zynq: Split slcr in two parts
ARM: zynq: Map I/O memory on clkc init
ARM: zynq: Add and use zynq_slcr_read/write() helper functions
ARM: zynq: Introduce zynq_slcr_unlock()
Steffen Trumtrar (3):
ARM: zynq: Move clock_init from slcr to common
ARM: zynq: Hang iomapped slcr address on device_node
ARM: zynq: Make zynq_slcr_base static
.../devicetree/bindings/clock/zynq-7000.txt | 4 +- arch/arm/boot/dts/zynq-7000.dtsi | 42 +++++----- arch/arm/mach-zynq/Kconfig | 1 + arch/arm/mach-zynq/common.c | 6 +- arch/arm/mach-zynq/common.h | 2 +- arch/arm/mach-zynq/slcr.c | 98 +++++++++++++++++++--- drivers/clk/zynq/clkc.c | 89 ++++++++++++++------ include/linux/clk/zynq.h | 2 +- 8 files changed, 179 insertions(+), 65 deletions(-)
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/9c62af17/attachment.sig>
PATCH 1/7 ARM: zynq: Move clock_init from slcr to common
From: Steffen Trumtrar <[email protected]>
Preparation step for next changes.
--- arch/arm/mach-zynq/common.c | 2 ++ arch/arm/mach-zynq/slcr.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-zynq/common.c +2 -0
@@ -64,6 +64,8 @@ static void __init zynq_init_machine(void)static void __init zynq_timer_init (void ) {zynq_slcr_init (); + +zynq_clock_init (zynq_slcr_base);clocksource_of_init (); }
arch/arm/mach-zynq/slcr.c +0 -2
@@ -106,8 +106,6 @@ int __init zynq_slcr_init(void)pr_info ("%s mapped to %p\n" , np->name, zynq_slcr_base); -zynq_clock_init (zynq_slcr_base); -of_node_put (np);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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/8d79f305/attachment.sig>
PATCH 2/7 ARM: zynq: Split slcr in two parts
In reply to Michal SimekSplit the slcr into an early part for unlocking and cpu starting and a later syscon driver.
Also add "syscon" compatible property for slcr.
--- arch/arm/boot/dts/zynq-7000.dtsi | 2 +- arch/arm/mach-zynq/Kconfig | 1 + arch/arm/mach-zynq/common.c | 4 +++- arch/arm/mach-zynq/common.h | 1 + arch/arm/mach-zynq/slcr.c | 20 ++++++++++++++++++++ 5 files changed, 26 insertions(+), 2 deletions(-)
arch/arm/boot/dts/zynq-7000.dtsi +1 -1
@@ -123,7 +123,7 @@ } ; slcr: slcr at f8000000 { - compatible = "xlnx,zynq-slcr"; + compatible = "xlnx,zynq-slcr", "syscon"; reg = <0xF8000000 0x1000>; clocks {
arch/arm/mach-zynq/Kconfig +1 -0
@@ -14,5 +14,6 @@ config ARCH_ZYNQ select SPARSE_IRQ select CADENCE_TTC_TIMER select ARM_GLOBAL_TIMER + select MFD_SYSCON help Support for Xilinx Zynq ARM Cortex A9 Platform
arch/arm/mach-zynq/common.c +3 -1
@@ -59,11 +59,13 @@ static void __init zynq_init_machine(void)of_platform_populate (NULL , of_default_bus_match_table,NULL ,NULL );platform_device_register (&zynq_cpuidle_device); + +zynq_slcr_init (); }static void __init zynq_timer_init (void ) { -zynq_slcr_init (); +zynq_early_slcr_init ();zynq_clock_init (zynq_slcr_base);clocksource_of_init ();
arch/arm/mach-zynq/common.h +1 -0
@@ -20,6 +20,7 @@void zynq_secondary_startup (void );extern int zynq_slcr_init (void ); +extern int zynq_early_slcr_init (void );extern void zynq_slcr_system_reset (void );extern void zynq_slcr_cpu_stop (int cpu);extern void zynq_slcr_cpu_start (int cpu);
arch/arm/mach-zynq/slcr.c +20 -0
@@ -15,7 +15,9 @@*/ #include <linux/io.h> +#include <linux/mfd/syscon.h> #include <linux/of_address.h> +#include <linux/regmap.h> #include <linux/clk/zynq.h> #include "common.h"
@@ -30,6 +32,7 @@#define SLCR_A9_CPU_RST 0x1void __iomem *zynq_slcr_base; +static struct regmap *zynq_slcr_regmap;/** * zynq_slcr_system_reset - Reset the entire system.
@@ -87,6 +90,23 @@ void zynq_slcr_cpu_stop(int cpu)*/ int __init zynq_slcr_init (void ) { + zynq_slcr_regmap =syscon_regmap_lookup_by_compatible ("xlnx,zynq-slcr" ); +if (IS_ERR (zynq_slcr_regmap)) { +pr_err ("%s: failed to find zynq-slcr\n" , __func__); +return -ENODEV ; + } + +return 0 ; +} + +/** +* zynq_early_slcr_init +* Returns 0 on success, negative errno otherwise. +* +* Called very early during boot from platform code to unlock SLCR. +*/ +int __init zynq_early_slcr_init (void ) +{struct device_node *np; np =of_find_compatible_node (NULL ,NULL ,"xlnx,zynq-slcr" );
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/963a3065/attachment.sig>
PATCH 3/7 ARM: zynq: Hang iomapped slcr address on device_node
In reply to Michal SimekFrom: Steffen Trumtrar <[email protected]>
For later usage by zynq clk driver.
--- arch/arm/mach-zynq/slcr.c | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/mach-zynq/slcr.c +2 -0
@@ -121,6 +121,8 @@ int __init zynq_early_slcr_init(void)BUG (); } + np->data = (__force void *)zynq_slcr_base; +/* unlock the SLCR so that registers can be changed */ writel (SLCR_UNLOCK_MAGIC , zynq_slcr_base +SLCR_UNLOCK_OFFSET );
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/acca4a1d/attachment.sig>
Re: [PATCH 3/7] ARM: zynq: Hang iomapped slcr address on device_node
Quoted 15 lines · Michal Simek
From: Steffen Trumtrar <[email protected]>
For later usage by zynq clk driver.
Signed-off-by Steffen Trumtrar <[email protected]>Signed-off-by Michal Simek <[email protected]>--- arch/arm/mach-zynq/slcr.c | 2 ++ 1 file changed, 2 insertions(+)arch/arm/mach-zynq/slcr.c +0
-0
arch/arm/mach-zynq/slcr.c int __init zynq_early_slcr_init(void) · line 124
Quoted 4 lines
arch/arm/mach-zynq/slcr.c +1
-0@@ -121,6 +121,8 @@ int __init zynq_early_slcr_init(void)BUG (); } + np->data = (__force void *)zynq_slcr_base;
This is quite unusual, we normally remap again if needed. Is there a reason you can't just have the driver request the resource and map it like most other ones do?
-Olof
Re: [PATCH 3/7] ARM: zynq: Hang iomapped slcr address on device_node
Quoted 19 lines · Olof Johansson
Quoted 18 lines · Michal Simek
From: Steffen Trumtrar <[email protected]>
For later usage by zynq clk driver.
Signed-off-by Steffen Trumtrar <[email protected]>Signed-off-by Michal Simek <[email protected]>--- arch/arm/mach-zynq/slcr.c | 2 ++ 1 file changed, 2 insertions(+)arch/arm/mach-zynq/slcr.c +0
-0@@ -121,6 +121,8 @@ int __init zynq_early_slcr_init(void)BUG (); }
Quoted 6 lines
arch/arm/mach-zynq/slcr.c int __init zynq_early_slcr_init(void) · line 124
Quoted 1 line
arch/arm/mach-zynq/slcr.c +1
-0+ np->data = (__force void *)zynq_slcr_base;This is quite unusual, we normally remap again if needed. Is there a reason you can't just have the driver request the resource and map it like most other ones do?
I took this patch from Steffen because remapping slcr again in clock driver is another mapping for the same IP. Use one ioremap region seems to me better if there is a way. Of course if this is strictly prohibited we can do another mapping in clock driver.
Here is the RFC I have sent after my discussion with Arnd that we should use early syscon initialization and regmap. This is just RFC to show slcr cleaning up.
http://permalink.gmane.org/gmane.linux.kernel/1651213
(Here is broken CLK part because clk subsystem uses clk_readl/clk_writel
- changing this is discussed in other threads)
Quoted 1 line
From v1 - regmap device separation was applied by Mark
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git tags/nodev
Quoted 1 line
From v2 - "mfd: syscon: Support early initialization"
I expected to get any comment from Arnd but I will respin this based on Lee's comments
To summarize this for future I would like to use access with regmap with one ioremap.
Thanks,
Michal
Signature · 14 lines
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/ Maintainer of Linux kernel - Xilinx Zynq ARM architecture Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 263 bytes Desc: OpenPGP digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140312/f612458f/attachment.sig>
PATCH 4/7 ARM: zynq: Map I/O memory on clkc init
In reply to Michal SimekThe clkc has its registers in the range of the slcr.
Instead of passing around the slcr base address pointer, let the clkc get the address from the DT.
This prepares the slcr to be a real driver with multiple memory ranges (slcr, clocks, pinctrl,...)
--- .../devicetree/bindings/clock/zynq-7000.txt | 4 +- arch/arm/boot/dts/zynq-7000.dtsi | 40 +++++----- arch/arm/mach-zynq/common.c | 2 +- drivers/clk/zynq/clkc.c | 89 +++++++++++++++------- include/linux/clk/zynq.h | 2 +- 5 files changed, 87 insertions(+), 50 deletions(-)
Documentation/devicetree/bindings/clock/zynq-7000.txt +3 -1
@@ -14,6 +14,7 @@ for all clock consumers of PS clocks. Required properties: - #clock-cells : Must be 1 - compatible : "xlnx,ps7-clkc" + - reg : SLCR offset and size taken via syscon < 0x100 0x100 > - ps-clk-frequency : Frequency of the oscillator providing ps_clk in HZ (usually 33 MHz oscillators are used for Zynq platforms) - clock-output-names : List of strings used to name the clock outputs. Shall be
@@ -83,10 +84,11 @@ Clock outputs: 47: dbg_apb Example: - clkc: clkc { + clkc: clkc at 100 { #clock-cells = <1>; compatible = "xlnx,ps7-clkc"; ps-clk-frequency = <33333333>; + reg = <0x100 0x100>; clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
arch/arm/boot/dts/zynq-7000.dtsi +19 -21
@@ -123,30 +123,28 @@ } ; slcr: slcr at f8000000 { + #address-cells = <1>; + #size-cells = <1>; compatible = "xlnx,zynq-slcr", "syscon"; reg = <0xF8000000 0x1000>; - clocks { - #address-cells = <1>; - #size-cells = <0>; - - clkc: clkc { - #clock-cells = <1>; - compatible = "xlnx,ps7-clkc"; - ps-clk-frequency = <33333333>; - fclk-enable = <0>; - clock-output-names = "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"; - }; + clkc: clkc at 100 { + #clock-cells = <1>; + compatible = "xlnx,ps7-clkc"; + ps-clk-frequency = <33333333>; + fclk-enable = <0>; + clock-output-names = "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"; + reg = <0x100 0x100>; }; };
arch/arm/mach-zynq/common.c +1 -1
@@ -67,7 +67,7 @@ static void __init zynq_timer_init(void) {zynq_early_slcr_init (); -zynq_clock_init (zynq_slcr_base); +zynq_clock_init ();clocksource_of_init (); }
drivers/clk/zynq/clkc.c +63 -26
105 lines not on this page · raw message
include/linux/clk/zynq.h +1 -1
@@ -22,7 +22,7 @@#include <linux/spinlock.h> -void zynq_clock_init (void __iomem *slcr); +void zynq_clock_init (void ); struct clk *clk_register_zynq_pll(const char *name, const char *parent, void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/bace6ff1/attachment-0001.sig>
PATCH 5/7 ARM: zynq: Make zynq_slcr_base static
In reply to Michal SimekFrom: Steffen Trumtrar <[email protected]>
The pointer doesn't need to be passed around any more. Make it static.
--- arch/arm/mach-zynq/common.h | 1 - arch/arm/mach-zynq/slcr.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-)
arch/arm/mach-zynq/common.h +0 -1
@@ -34,7 +34,6 @@ extern int zynq_cpun_start(u32 address, int cpu);extern struct smp_operations zynq_smp_ops__initdata ;#endif -extern void __iomem *zynq_slcr_base;extern void __iomem *zynq_scu_base;/* Hotplug */
arch/arm/mach-zynq/slcr.c +1 -1
@@ -31,7 +31,7 @@#define SLCR_A9_CPU_CLKSTOP 0x10#define SLCR_A9_CPU_RST 0x1 -void __iomem *zynq_slcr_base; +static void __iomem *zynq_slcr_base;static struct regmap *zynq_slcr_regmap;/**
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/efdfb039/attachment.sig>
PATCH 6/7 ARM: zynq: Add and use zynq_slcr_read/write() helper functions
In reply to Michal SimekUse zynq_slcr_read/write helper functions for reg access instead of readl/writel.
Also use regmap when it is ready.
--- arch/arm/mach-zynq/slcr.c | 56 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 8 deletions(-)
arch/arm/mach-zynq/slcr.c +48 -8
@@ -35,6 +35,42 @@ static void __iomem *zynq_slcr_base;static struct regmap *zynq_slcr_regmap;/** +* zynq_slcr_write - Write to a register in SLCR block +* +* @val: Value to write to the register +* @offset: Register offset in SLCR block +* +* return: a negative value on error, 0 on success +*/ +static int zynq_slcr_write (u32 val,u32 offset) +{ +if (!zynq_slcr_regmap) { +writel (val, zynq_slcr_base + offset); +return 0 ; + } + +return regmap_write (zynq_slcr_regmap, offset, val); +} + +/** +* zynq_slcr_read - Read a register in SLCR block +* +* @val: Pointer to value to be read from SLCR +* @offset: Register offset in SLCR block +* +* return: a negative value on error, 0 on success +*/ +static int zynq_slcr_read (u32 *val,u32 offset) +{ +if (zynq_slcr_regmap) +return regmap_read (zynq_slcr_regmap, offset, val); + + *val =readl (zynq_slcr_base + offset); + +return 0 ; +} + +/** * zynq_slcr_system_reset - Reset the entire system. */ void zynq_slcr_system_reset (void )
@@ -53,9 +89,9 @@ void zynq_slcr_system_reset(void)* the FSBL not loading the bitstream after soft-reboot * This is a temporary solution until we know more. */ - reboot =readl (zynq_slcr_base +SLCR_REBOOT_STATUS_OFFSET ); -writel (reboot &0xF0FFFFFF , zynq_slcr_base +SLCR_REBOOT_STATUS_OFFSET ); -writel (1 , zynq_slcr_base +SLCR_PS_RST_CTRL_OFFSET ); +zynq_slcr_read (&reboot,SLCR_REBOOT_STATUS_OFFSET ); +zynq_slcr_write (reboot &0xF0FFFFFF ,SLCR_REBOOT_STATUS_OFFSET ); +zynq_slcr_write (1 ,SLCR_PS_RST_CTRL_OFFSET ); }/**
@@ -64,11 +100,13 @@ void zynq_slcr_system_reset(void)*/ void zynq_slcr_cpu_start (int cpu) { -u32 reg =readl (zynq_slcr_base +SLCR_A9_CPU_RST_CTRL_OFFSET ); +u32 reg; + +zynq_slcr_read (®,SLCR_A9_CPU_RST_CTRL_OFFSET ); reg &= ~(SLCR_A9_CPU_RST << cpu); -writel (reg, zynq_slcr_base +SLCR_A9_CPU_RST_CTRL_OFFSET ); +zynq_slcr_write (reg,SLCR_A9_CPU_RST_CTRL_OFFSET ); reg &= ~(SLCR_A9_CPU_CLKSTOP << cpu); -writel (reg, zynq_slcr_base +SLCR_A9_CPU_RST_CTRL_OFFSET ); +zynq_slcr_write (reg,SLCR_A9_CPU_RST_CTRL_OFFSET ); }/**
@@ -77,9 +115,11 @@ void zynq_slcr_cpu_start(int cpu)*/ void zynq_slcr_cpu_stop (int cpu) { -u32 reg =readl (zynq_slcr_base +SLCR_A9_CPU_RST_CTRL_OFFSET ); +u32 reg; + +zynq_slcr_read (®,SLCR_A9_CPU_RST_CTRL_OFFSET ); reg |= (SLCR_A9_CPU_CLKSTOP |SLCR_A9_CPU_RST ) << cpu; -writel (reg, zynq_slcr_base +SLCR_A9_CPU_RST_CTRL_OFFSET ); +zynq_slcr_write (reg,SLCR_A9_CPU_RST_CTRL_OFFSET ); }/**
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/45056c3f/attachment.sig>
PATCH 7/7 ARM: zynq: Introduce zynq_slcr_unlock()
In reply to Michal SimekCall special function for unlocking SLCR.
--- arch/arm/mach-zynq/slcr.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
arch/arm/mach-zynq/slcr.c +14 -2
@@ -71,6 +71,18 @@ static int zynq_slcr_read(u32 *val, u32 offset) }/** +* zynq_slcr_unlock - Unlock SLCR registers +* +* return: a negative value on error, 0 on success +*/ +static inline int zynq_slcr_unlock (void ) +{ +zynq_slcr_write (SLCR_UNLOCK_MAGIC ,SLCR_UNLOCK_OFFSET ); + +return 0 ; +} + +/** * zynq_slcr_system_reset - Reset the entire system. */ void zynq_slcr_system_reset (void )
@@ -82,7 +94,7 @@ void zynq_slcr_system_reset(void)* Note that this seems to require raw i/o * functions or there's a lockup? */ -writel (SLCR_UNLOCK_MAGIC , zynq_slcr_base +SLCR_UNLOCK_OFFSET ); +zynq_slcr_unlock ();/* * Clear 0x0F000000 bits of reboot status register to workaround
@@ -164,7 +176,7 @@ int __init zynq_early_slcr_init(void) np->data = (__force void *)zynq_slcr_base;/* unlock the SLCR so that registers can be changed */ -writel (SLCR_UNLOCK_MAGIC , zynq_slcr_base +SLCR_UNLOCK_OFFSET ); +zynq_slcr_unlock ();pr_info ("%s mapped to %p\n" , np->name, zynq_slcr_base);
--
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.infradead.org/pipermail/linux-arm-kernel/attachments/20140106/38ae2957/attachment.sig>