Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'zynq-cleanup-for-3.15-v2' of git://git.xilinx.com/linux-xlnx into next/cleanup2

Merge "arm: Xilinx Zynq cleanup patches for v3.15" from Michal Simek:

- Redesign SLCR initialization to enable
driver developing which targets SLCR space

* tag 'zynq-cleanup-for-3.15-v2' of git://git.xilinx.com/linux-xlnx:
ARM: zynq: Add waituart implementation
ARM: zynq: Move of_clk_init from clock driver
ARM: zynq: Introduce zynq_slcr_unlock()
ARM: zynq: Add and use zynq_slcr_read/write() helper functions
ARM: zynq: Make zynq_slcr_base static
ARM: zynq: Map I/O memory on clkc init
ARM: zynq: Hang iomapped slcr address on device_node
ARM: zynq: Split slcr in two parts
ARM: zynq: Move clock_init from slcr to common
arm: dt: zynq: Add fclk-enable property to clkc node

[Arnd: remove SOC_BUS support from pull request]

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+187 -67
+3 -1
Documentation/devicetree/bindings/clock/zynq-7000.txt
··· 14 14 Required properties: 15 15 - #clock-cells : Must be 1 16 16 - compatible : "xlnx,ps7-clkc" 17 + - reg : SLCR offset and size taken via syscon < 0x100 0x100 > 17 18 - ps-clk-frequency : Frequency of the oscillator providing ps_clk in HZ 18 19 (usually 33 MHz oscillators are used for Zynq platforms) 19 20 - clock-output-names : List of strings used to name the clock outputs. Shall be ··· 88 87 47: dbg_apb 89 88 90 89 Example: 91 - clkc: clkc { 90 + clkc: clkc@100 { 92 91 #clock-cells = <1>; 93 92 compatible = "xlnx,ps7-clkc"; 94 93 ps-clk-frequency = <33333333>; 94 + reg = <0x100 0x100>; 95 95 clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", 96 96 "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", 97 97 "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
+21 -22
arch/arm/boot/dts/zynq-7000.dtsi
··· 123 123 } ; 124 124 125 125 slcr: slcr@f8000000 { 126 - compatible = "xlnx,zynq-slcr"; 126 + #address-cells = <1>; 127 + #size-cells = <1>; 128 + compatible = "xlnx,zynq-slcr", "syscon"; 127 129 reg = <0xF8000000 0x1000>; 128 - 129 - clocks { 130 - #address-cells = <1>; 131 - #size-cells = <0>; 132 - 133 - clkc: clkc { 134 - #clock-cells = <1>; 135 - compatible = "xlnx,ps7-clkc"; 136 - ps-clk-frequency = <33333333>; 137 - clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", 138 - "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", 139 - "dci", "lqspi", "smc", "pcap", "gem0", "gem1", 140 - "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", 141 - "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", 142 - "dma", "usb0_aper", "usb1_aper", "gem0_aper", 143 - "gem1_aper", "sdio0_aper", "sdio1_aper", 144 - "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", 145 - "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", 146 - "gpio_aper", "lqspi_aper", "smc_aper", "swdt", 147 - "dbg_trc", "dbg_apb"; 148 - }; 130 + ranges; 131 + clkc: clkc@100 { 132 + #clock-cells = <1>; 133 + compatible = "xlnx,ps7-clkc"; 134 + ps-clk-frequency = <33333333>; 135 + fclk-enable = <0>; 136 + clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", 137 + "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", 138 + "dci", "lqspi", "smc", "pcap", "gem0", "gem1", 139 + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", 140 + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", 141 + "dma", "usb0_aper", "usb1_aper", "gem0_aper", 142 + "gem1_aper", "sdio0_aper", "sdio1_aper", 143 + "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", 144 + "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", 145 + "gpio_aper", "lqspi_aper", "smc_aper", "swdt", 146 + "dbg_trc", "dbg_apb"; 147 + reg = <0x100 0x100>; 149 148 }; 150 149 }; 151 150
+3
arch/arm/include/debug/zynq.S
··· 42 42 .endm 43 43 44 44 .macro waituart,rd,rx 45 + 1001: ldr \rd, [\rx, #UART_SR_OFFSET] 46 + tst \rd, #UART_SR_TXEMPTY 47 + beq 1001b 45 48 .endm 46 49 47 50 .macro busyuart,rd,rx
+1
arch/arm/mach-zynq/Kconfig
··· 14 14 select SPARSE_IRQ 15 15 select CADENCE_TTC_TIMER 16 16 select ARM_GLOBAL_TIMER 17 + select MFD_SYSCON 17 18 help 18 19 Support for Xilinx Zynq ARM Cortex A9 Platform
+7 -1
arch/arm/mach-zynq/common.c
··· 19 19 #include <linux/cpumask.h> 20 20 #include <linux/platform_device.h> 21 21 #include <linux/clk.h> 22 + #include <linux/clk-provider.h> 22 23 #include <linux/clk/zynq.h> 23 24 #include <linux/clocksource.h> 24 25 #include <linux/of_address.h> ··· 73 72 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 74 73 75 74 platform_device_register(&zynq_cpuidle_device); 75 + 76 + zynq_slcr_init(); 76 77 } 77 78 78 79 static void __init zynq_timer_init(void) 79 80 { 80 - zynq_slcr_init(); 81 + zynq_early_slcr_init(); 82 + 83 + zynq_clock_init(); 84 + of_clk_init(NULL); 81 85 clocksource_of_init(); 82 86 } 83 87
+1 -1
arch/arm/mach-zynq/common.h
··· 20 20 void zynq_secondary_startup(void); 21 21 22 22 extern int zynq_slcr_init(void); 23 + extern int zynq_early_slcr_init(void); 23 24 extern void zynq_slcr_system_reset(void); 24 25 extern void zynq_slcr_cpu_stop(int cpu); 25 26 extern void zynq_slcr_cpu_start(int cpu); ··· 34 33 extern struct smp_operations zynq_smp_ops __initdata; 35 34 #endif 36 35 37 - extern void __iomem *zynq_slcr_base; 38 36 extern void __iomem *zynq_scu_base; 39 37 40 38 /* Hotplug */
+89 -15
arch/arm/mach-zynq/slcr.c
··· 15 15 */ 16 16 17 17 #include <linux/io.h> 18 + #include <linux/mfd/syscon.h> 18 19 #include <linux/of_address.h> 20 + #include <linux/regmap.h> 19 21 #include <linux/clk/zynq.h> 20 22 #include "common.h" 21 23 ··· 31 29 #define SLCR_A9_CPU_CLKSTOP 0x10 32 30 #define SLCR_A9_CPU_RST 0x1 33 31 34 - void __iomem *zynq_slcr_base; 32 + static void __iomem *zynq_slcr_base; 33 + static struct regmap *zynq_slcr_regmap; 34 + 35 + /** 36 + * zynq_slcr_write - Write to a register in SLCR block 37 + * 38 + * @val: Value to write to the register 39 + * @offset: Register offset in SLCR block 40 + * 41 + * Return: a negative value on error, 0 on success 42 + */ 43 + static int zynq_slcr_write(u32 val, u32 offset) 44 + { 45 + if (!zynq_slcr_regmap) { 46 + writel(val, zynq_slcr_base + offset); 47 + return 0; 48 + } 49 + 50 + return regmap_write(zynq_slcr_regmap, offset, val); 51 + } 52 + 53 + /** 54 + * zynq_slcr_read - Read a register in SLCR block 55 + * 56 + * @val: Pointer to value to be read from SLCR 57 + * @offset: Register offset in SLCR block 58 + * 59 + * Return: a negative value on error, 0 on success 60 + */ 61 + static int zynq_slcr_read(u32 *val, u32 offset) 62 + { 63 + if (zynq_slcr_regmap) 64 + return regmap_read(zynq_slcr_regmap, offset, val); 65 + 66 + *val = readl(zynq_slcr_base + offset); 67 + 68 + return 0; 69 + } 70 + 71 + /** 72 + * zynq_slcr_unlock - Unlock SLCR registers 73 + * 74 + * Return: a negative value on error, 0 on success 75 + */ 76 + static inline int zynq_slcr_unlock(void) 77 + { 78 + zynq_slcr_write(SLCR_UNLOCK_MAGIC, SLCR_UNLOCK_OFFSET); 79 + 80 + return 0; 81 + } 35 82 36 83 /** 37 84 * zynq_slcr_system_reset - Reset the entire system. ··· 94 43 * Note that this seems to require raw i/o 95 44 * functions or there's a lockup? 96 45 */ 97 - writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK_OFFSET); 46 + zynq_slcr_unlock(); 98 47 99 48 /* 100 49 * Clear 0x0F000000 bits of reboot status register to workaround 101 50 * the FSBL not loading the bitstream after soft-reboot 102 51 * This is a temporary solution until we know more. 103 52 */ 104 - reboot = readl(zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET); 105 - writel(reboot & 0xF0FFFFFF, zynq_slcr_base + SLCR_REBOOT_STATUS_OFFSET); 106 - writel(1, zynq_slcr_base + SLCR_PS_RST_CTRL_OFFSET); 53 + zynq_slcr_read(&reboot, SLCR_REBOOT_STATUS_OFFSET); 54 + zynq_slcr_write(reboot & 0xF0FFFFFF, SLCR_REBOOT_STATUS_OFFSET); 55 + zynq_slcr_write(1, SLCR_PS_RST_CTRL_OFFSET); 107 56 } 108 57 109 58 /** ··· 112 61 */ 113 62 void zynq_slcr_cpu_start(int cpu) 114 63 { 115 - u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); 64 + u32 reg; 65 + 66 + zynq_slcr_read(&reg, SLCR_A9_CPU_RST_CTRL_OFFSET); 116 67 reg &= ~(SLCR_A9_CPU_RST << cpu); 117 - writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); 68 + zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET); 118 69 reg &= ~(SLCR_A9_CPU_CLKSTOP << cpu); 119 - writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); 70 + zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET); 120 71 } 121 72 122 73 /** ··· 127 74 */ 128 75 void zynq_slcr_cpu_stop(int cpu) 129 76 { 130 - u32 reg = readl(zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); 77 + u32 reg; 78 + 79 + zynq_slcr_read(&reg, SLCR_A9_CPU_RST_CTRL_OFFSET); 131 80 reg |= (SLCR_A9_CPU_CLKSTOP | SLCR_A9_CPU_RST) << cpu; 132 - writel(reg, zynq_slcr_base + SLCR_A9_CPU_RST_CTRL_OFFSET); 81 + zynq_slcr_write(reg, SLCR_A9_CPU_RST_CTRL_OFFSET); 133 82 } 134 83 135 84 /** 136 - * zynq_slcr_init 137 - * Returns 0 on success, negative errno otherwise. 85 + * zynq_slcr_init - Regular slcr driver init 86 + * 87 + * Return: 0 on success, negative errno otherwise. 138 88 * 139 89 * Called early during boot from platform code to remap SLCR area. 140 90 */ 141 91 int __init zynq_slcr_init(void) 92 + { 93 + zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr"); 94 + if (IS_ERR(zynq_slcr_regmap)) { 95 + pr_err("%s: failed to find zynq-slcr\n", __func__); 96 + return -ENODEV; 97 + } 98 + 99 + return 0; 100 + } 101 + 102 + /** 103 + * zynq_early_slcr_init - Early slcr init function 104 + * 105 + * Return: 0 on success, negative errno otherwise. 106 + * 107 + * Called very early during boot from platform code to unlock SLCR. 108 + */ 109 + int __init zynq_early_slcr_init(void) 142 110 { 143 111 struct device_node *np; 144 112 ··· 175 101 BUG(); 176 102 } 177 103 104 + np->data = (__force void *)zynq_slcr_base; 105 + 178 106 /* unlock the SLCR so that registers can be changed */ 179 - writel(SLCR_UNLOCK_MAGIC, zynq_slcr_base + SLCR_UNLOCK_OFFSET); 107 + zynq_slcr_unlock(); 180 108 181 109 pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); 182 - 183 - zynq_clock_init(zynq_slcr_base); 184 110 185 111 of_node_put(np); 186 112
+61 -26
drivers/clk/zynq/clkc.c
··· 21 21 #include <linux/clk/zynq.h> 22 22 #include <linux/clk-provider.h> 23 23 #include <linux/of.h> 24 + #include <linux/of_address.h> 24 25 #include <linux/slab.h> 25 26 #include <linux/string.h> 26 27 #include <linux/io.h> 27 28 28 - static void __iomem *zynq_slcr_base_priv; 29 + static void __iomem *zynq_clkc_base; 29 30 30 - #define SLCR_ARMPLL_CTRL (zynq_slcr_base_priv + 0x100) 31 - #define SLCR_DDRPLL_CTRL (zynq_slcr_base_priv + 0x104) 32 - #define SLCR_IOPLL_CTRL (zynq_slcr_base_priv + 0x108) 33 - #define SLCR_PLL_STATUS (zynq_slcr_base_priv + 0x10c) 34 - #define SLCR_ARM_CLK_CTRL (zynq_slcr_base_priv + 0x120) 35 - #define SLCR_DDR_CLK_CTRL (zynq_slcr_base_priv + 0x124) 36 - #define SLCR_DCI_CLK_CTRL (zynq_slcr_base_priv + 0x128) 37 - #define SLCR_APER_CLK_CTRL (zynq_slcr_base_priv + 0x12c) 38 - #define SLCR_GEM0_CLK_CTRL (zynq_slcr_base_priv + 0x140) 39 - #define SLCR_GEM1_CLK_CTRL (zynq_slcr_base_priv + 0x144) 40 - #define SLCR_SMC_CLK_CTRL (zynq_slcr_base_priv + 0x148) 41 - #define SLCR_LQSPI_CLK_CTRL (zynq_slcr_base_priv + 0x14c) 42 - #define SLCR_SDIO_CLK_CTRL (zynq_slcr_base_priv + 0x150) 43 - #define SLCR_UART_CLK_CTRL (zynq_slcr_base_priv + 0x154) 44 - #define SLCR_SPI_CLK_CTRL (zynq_slcr_base_priv + 0x158) 45 - #define SLCR_CAN_CLK_CTRL (zynq_slcr_base_priv + 0x15c) 46 - #define SLCR_CAN_MIOCLK_CTRL (zynq_slcr_base_priv + 0x160) 47 - #define SLCR_DBG_CLK_CTRL (zynq_slcr_base_priv + 0x164) 48 - #define SLCR_PCAP_CLK_CTRL (zynq_slcr_base_priv + 0x168) 49 - #define SLCR_FPGA0_CLK_CTRL (zynq_slcr_base_priv + 0x170) 50 - #define SLCR_621_TRUE (zynq_slcr_base_priv + 0x1c4) 51 - #define SLCR_SWDT_CLK_SEL (zynq_slcr_base_priv + 0x304) 31 + #define SLCR_ARMPLL_CTRL (zynq_clkc_base + 0x00) 32 + #define SLCR_DDRPLL_CTRL (zynq_clkc_base + 0x04) 33 + #define SLCR_IOPLL_CTRL (zynq_clkc_base + 0x08) 34 + #define SLCR_PLL_STATUS (zynq_clkc_base + 0x0c) 35 + #define SLCR_ARM_CLK_CTRL (zynq_clkc_base + 0x20) 36 + #define SLCR_DDR_CLK_CTRL (zynq_clkc_base + 0x24) 37 + #define SLCR_DCI_CLK_CTRL (zynq_clkc_base + 0x28) 38 + #define SLCR_APER_CLK_CTRL (zynq_clkc_base + 0x2c) 39 + #define SLCR_GEM0_CLK_CTRL (zynq_clkc_base + 0x40) 40 + #define SLCR_GEM1_CLK_CTRL (zynq_clkc_base + 0x44) 41 + #define SLCR_SMC_CLK_CTRL (zynq_clkc_base + 0x48) 42 + #define SLCR_LQSPI_CLK_CTRL (zynq_clkc_base + 0x4c) 43 + #define SLCR_SDIO_CLK_CTRL (zynq_clkc_base + 0x50) 44 + #define SLCR_UART_CLK_CTRL (zynq_clkc_base + 0x54) 45 + #define SLCR_SPI_CLK_CTRL (zynq_clkc_base + 0x58) 46 + #define SLCR_CAN_CLK_CTRL (zynq_clkc_base + 0x5c) 47 + #define SLCR_CAN_MIOCLK_CTRL (zynq_clkc_base + 0x60) 48 + #define SLCR_DBG_CLK_CTRL (zynq_clkc_base + 0x64) 49 + #define SLCR_PCAP_CLK_CTRL (zynq_clkc_base + 0x68) 50 + #define SLCR_FPGA0_CLK_CTRL (zynq_clkc_base + 0x70) 51 + #define SLCR_621_TRUE (zynq_clkc_base + 0xc4) 52 + #define SLCR_SWDT_CLK_SEL (zynq_clkc_base + 0x204) 52 53 53 54 #define NUM_MIO_PINS 54 54 55 ··· 570 569 571 570 CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc", zynq_clk_setup); 572 571 573 - void __init zynq_clock_init(void __iomem *slcr_base) 572 + void __init zynq_clock_init(void) 574 573 { 575 - zynq_slcr_base_priv = slcr_base; 576 - of_clk_init(NULL); 574 + struct device_node *np; 575 + struct device_node *slcr; 576 + struct resource res; 577 + 578 + np = of_find_compatible_node(NULL, NULL, "xlnx,ps7-clkc"); 579 + if (!np) { 580 + pr_err("%s: clkc node not found\n", __func__); 581 + goto np_err; 582 + } 583 + 584 + if (of_address_to_resource(np, 0, &res)) { 585 + pr_err("%s: failed to get resource\n", np->name); 586 + goto np_err; 587 + } 588 + 589 + slcr = of_get_parent(np); 590 + 591 + if (slcr->data) { 592 + zynq_clkc_base = (__force void __iomem *)slcr->data + res.start; 593 + } else { 594 + pr_err("%s: Unable to get I/O memory\n", np->name); 595 + of_node_put(slcr); 596 + goto np_err; 597 + } 598 + 599 + pr_info("%s: clkc starts at %p\n", __func__, zynq_clkc_base); 600 + 601 + of_node_put(slcr); 602 + of_node_put(np); 603 + 604 + return; 605 + 606 + np_err: 607 + of_node_put(np); 608 + BUG(); 609 + return; 577 610 }
+1 -1
include/linux/clk/zynq.h
··· 22 22 23 23 #include <linux/spinlock.h> 24 24 25 - void zynq_clock_init(void __iomem *slcr); 25 + void zynq_clock_init(void); 26 26 27 27 struct clk *clk_register_zynq_pll(const char *name, const char *parent, 28 28 void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,