aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/clock/zynq-7000.txt123
-rw-r--r--arch/arm/boot/dts/zynq-7000.dtsi71
-rw-r--r--arch/arm/boot/dts/zynq-zc702.dts4
-rw-r--r--arch/arm/mach-zynq/slcr.c2
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/clk-zynq.c378
-rw-r--r--drivers/clk/zynq/Makefile3
-rw-r--r--drivers/clk/zynq/clkc.c533
-rw-r--r--drivers/clk/zynq/pll.c235
-rw-r--r--drivers/clocksource/cadence_ttc_timer.c23
-rw-r--r--drivers/tty/serial/xilinx_uartps.c85
-rw-r--r--include/linux/clk/zynq.h8
12 files changed, 972 insertions, 495 deletions
diff --git a/Documentation/devicetree/bindings/clock/zynq-7000.txt b/Documentation/devicetree/bindings/clock/zynq-7000.txt
index 23ae1db1bc13..d99af878f5d7 100644
--- a/Documentation/devicetree/bindings/clock/zynq-7000.txt
+++ b/Documentation/devicetree/bindings/clock/zynq-7000.txt
@@ -6,50 +6,99 @@ The purpose of this document is to document their usage.
6See clock_bindings.txt for more information on the generic clock bindings. 6See clock_bindings.txt for more information on the generic clock bindings.
7See Chapter 25 of Zynq TRM for more information about Zynq clocks. 7See Chapter 25 of Zynq TRM for more information about Zynq clocks.
8 8
9== PLLs == 9== Clock Controller ==
10 10The clock controller is a logical abstraction of Zynq's clock tree. It reads
11Used to describe the ARM_PLL, DDR_PLL, and IO_PLL. 11required input clock frequencies from the devicetree and acts as clock provider
12for all clock consumers of PS clocks.
12 13
13Required properties: 14Required properties:
14- #clock-cells : shall be 0 (only one clock is output from this node) 15 - #clock-cells : Must be 1
15- compatible : "xlnx,zynq-pll" 16 - compatible : "xlnx,ps7-clkc"
16- reg : pair of u32 values, which are the address offsets within the SLCR 17 - ps-clk-frequency : Frequency of the oscillator providing ps_clk in HZ
17 of the relevant PLL_CTRL register and PLL_CFG register respectively 18 (usually 33 MHz oscillators are used for Zynq platforms)
18- clocks : phandle for parent clock. should be the phandle for ps_clk 19 - clock-output-names : List of strings used to name the clock outputs. Shall be
20 a list of the outputs given below.
19 21
20Optional properties: 22Optional properties:
21- clock-output-names : name of the output clock 23 - clocks : as described in the clock bindings
22 24 - clock-names : as described in the clock bindings
23Example:
24 armpll: armpll {
25 #clock-cells = <0>;
26 compatible = "xlnx,zynq-pll";
27 clocks = <&ps_clk>;
28 reg = <0x100 0x110>;
29 clock-output-names = "armpll";
30 };
31
32== Peripheral clocks ==
33 25
34Describes clock node for the SDIO, SMC, SPI, QSPI, and UART clocks. 26Clock inputs:
27The following strings are optional parameters to the 'clock-names' property in
28order to provide an optional (E)MIO clock source.
29 - swdt_ext_clk
30 - gem0_emio_clk
31 - gem1_emio_clk
32 - mio_clk_XX # with XX = 00..53
33...
35 34
36Required properties: 35Clock outputs:
37- #clock-cells : shall be 1 36 0: armpll
38- compatible : "xlnx,zynq-periph-clock" 37 1: ddrpll
39- reg : a single u32 value, describing the offset within the SLCR where 38 2: iopll
40 the CLK_CTRL register is found for this peripheral 39 3: cpu_6or4x
41- clocks : phandle for parent clocks. should hold phandles for 40 4: cpu_3or2x
42 the IO_PLL, ARM_PLL, and DDR_PLL in order 41 5: cpu_2x
43- clock-output-names : names of the output clock(s). For peripherals that have 42 6: cpu_1x
44 two output clocks (for example, the UART), two clocks 43 7: ddr2x
45 should be listed. 44 8: ddr3x
45 9: dci
46 10: lqspi
47 11: smc
48 12: pcap
49 13: gem0
50 14: gem1
51 15: fclk0
52 16: fclk1
53 17: fclk2
54 18: fclk3
55 19: can0
56 20: can1
57 21: sdio0
58 22: sdio1
59 23: uart0
60 24: uart1
61 25: spi0
62 26: spi1
63 27: dma
64 28: usb0_aper
65 29: usb1_aper
66 30: gem0_aper
67 31: gem1_aper
68 32: sdio0_aper
69 33: sdio1_aper
70 34: spi0_aper
71 35: spi1_aper
72 36: can0_aper
73 37: can1_aper
74 38: i2c0_aper
75 39: i2c1_aper
76 40: uart0_aper
77 41: uart1_aper
78 42: gpio_aper
79 43: lqspi_aper
80 44: smc_aper
81 45: swdt
82 46: dbg_trc
83 47: dbg_apb
46 84
47Example: 85Example:
48 uart_clk: uart_clk { 86 clkc: clkc {
49 #clock-cells = <1>; 87 #clock-cells = <1>;
50 compatible = "xlnx,zynq-periph-clock"; 88 compatible = "xlnx,ps7-clkc";
51 clocks = <&iopll &armpll &ddrpll>; 89 ps-clk-frequency = <33333333>;
52 reg = <0x154>; 90 clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
53 clock-output-names = "uart0_ref_clk", 91 "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
54 "uart1_ref_clk"; 92 "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
93 "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
94 "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
95 "dma", "usb0_aper", "usb1_aper", "gem0_aper",
96 "gem1_aper", "sdio0_aper", "sdio1_aper",
97 "spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
98 "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
99 "gpio_aper", "lqspi_aper", "smc_aper", "swdt",
100 "dbg_trc", "dbg_apb";
101 # optional props
102 clocks = <&clkc 16>, <&clk_foo>;
103 clock-names = "gem1_emio_clk", "can_mio_clk_23";
55 }; 104 };
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
index 14fb2e609bab..0dbee2c23905 100644
--- a/arch/arm/boot/dts/zynq-7000.dtsi
+++ b/arch/arm/boot/dts/zynq-7000.dtsi
@@ -49,16 +49,18 @@
49 49
50 uart0: uart@e0000000 { 50 uart0: uart@e0000000 {
51 compatible = "xlnx,xuartps"; 51 compatible = "xlnx,xuartps";
52 clocks = <&clkc 23>, <&clkc 40>;
53 clock-names = "ref_clk", "aper_clk";
52 reg = <0xE0000000 0x1000>; 54 reg = <0xE0000000 0x1000>;
53 interrupts = <0 27 4>; 55 interrupts = <0 27 4>;
54 clocks = <&uart_clk 0>;
55 }; 56 };
56 57
57 uart1: uart@e0001000 { 58 uart1: uart@e0001000 {
58 compatible = "xlnx,xuartps"; 59 compatible = "xlnx,xuartps";
60 clocks = <&clkc 24>, <&clkc 41>;
61 clock-names = "ref_clk", "aper_clk";
59 reg = <0xE0001000 0x1000>; 62 reg = <0xE0001000 0x1000>;
60 interrupts = <0 50 4>; 63 interrupts = <0 50 4>;
61 clocks = <&uart_clk 1>;
62 }; 64 };
63 65
64 slcr: slcr@f8000000 { 66 slcr: slcr@f8000000 {
@@ -69,50 +71,21 @@
69 #address-cells = <1>; 71 #address-cells = <1>;
70 #size-cells = <0>; 72 #size-cells = <0>;
71 73
72 ps_clk: ps_clk { 74 clkc: clkc {
73 #clock-cells = <0>;
74 compatible = "fixed-clock";
75 /* clock-frequency set in board-specific file */
76 clock-output-names = "ps_clk";
77 };
78 armpll: armpll {
79 #clock-cells = <0>;
80 compatible = "xlnx,zynq-pll";
81 clocks = <&ps_clk>;
82 reg = <0x100 0x110>;
83 clock-output-names = "armpll";
84 };
85 ddrpll: ddrpll {
86 #clock-cells = <0>;
87 compatible = "xlnx,zynq-pll";
88 clocks = <&ps_clk>;
89 reg = <0x104 0x114>;
90 clock-output-names = "ddrpll";
91 };
92 iopll: iopll {
93 #clock-cells = <0>;
94 compatible = "xlnx,zynq-pll";
95 clocks = <&ps_clk>;
96 reg = <0x108 0x118>;
97 clock-output-names = "iopll";
98 };
99 uart_clk: uart_clk {
100 #clock-cells = <1>;
101 compatible = "xlnx,zynq-periph-clock";
102 clocks = <&iopll &armpll &ddrpll>;
103 reg = <0x154>;
104 clock-output-names = "uart0_ref_clk",
105 "uart1_ref_clk";
106 };
107 cpu_clk: cpu_clk {
108 #clock-cells = <1>; 75 #clock-cells = <1>;
109 compatible = "xlnx,zynq-cpu-clock"; 76 compatible = "xlnx,ps7-clkc";
110 clocks = <&iopll &armpll &ddrpll>; 77 ps-clk-frequency = <33333333>;
111 reg = <0x120 0x1C4>; 78 clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
112 clock-output-names = "cpu_6x4x", 79 "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
113 "cpu_3x2x", 80 "dci", "lqspi", "smc", "pcap", "gem0", "gem1",
114 "cpu_2x", 81 "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1",
115 "cpu_1x"; 82 "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1",
83 "dma", "usb0_aper", "usb1_aper", "gem0_aper",
84 "gem1_aper", "sdio0_aper", "sdio1_aper",
85 "spi0_aper", "spi1_aper", "can0_aper", "can1_aper",
86 "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper",
87 "gpio_aper", "lqspi_aper", "smc_aper", "swdt",
88 "dbg_trc", "dbg_apb";
116 }; 89 };
117 }; 90 };
118 }; 91 };
@@ -121,9 +94,8 @@
121 interrupt-parent = <&intc>; 94 interrupt-parent = <&intc>;
122 interrupts = < 0 10 4 0 11 4 0 12 4 >; 95 interrupts = < 0 10 4 0 11 4 0 12 4 >;
123 compatible = "cdns,ttc"; 96 compatible = "cdns,ttc";
97 clocks = <&clkc 6>;
124 reg = <0xF8001000 0x1000>; 98 reg = <0xF8001000 0x1000>;
125 clocks = <&cpu_clk 3>;
126 clock-names = "cpu_1x";
127 clock-ranges; 99 clock-ranges;
128 }; 100 };
129 101
@@ -131,9 +103,8 @@
131 interrupt-parent = <&intc>; 103 interrupt-parent = <&intc>;
132 interrupts = < 0 37 4 0 38 4 0 39 4 >; 104 interrupts = < 0 37 4 0 38 4 0 39 4 >;
133 compatible = "cdns,ttc"; 105 compatible = "cdns,ttc";
106 clocks = <&clkc 6>;
134 reg = <0xF8002000 0x1000>; 107 reg = <0xF8002000 0x1000>;
135 clocks = <&cpu_clk 3>;
136 clock-names = "cpu_1x";
137 clock-ranges; 108 clock-ranges;
138 }; 109 };
139 scutimer: scutimer@f8f00600 { 110 scutimer: scutimer@f8f00600 {
@@ -141,7 +112,7 @@
141 interrupts = < 1 13 0x301 >; 112 interrupts = < 1 13 0x301 >;
142 compatible = "arm,cortex-a9-twd-timer"; 113 compatible = "arm,cortex-a9-twd-timer";
143 reg = < 0xf8f00600 0x20 >; 114 reg = < 0xf8f00600 0x20 >;
144 clocks = <&cpu_clk 1>; 115 clocks = <&clkc 4>;
145 } ; 116 } ;
146 }; 117 };
147}; 118};
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts
index 86f44d5b0265..e25a307438ad 100644
--- a/arch/arm/boot/dts/zynq-zc702.dts
+++ b/arch/arm/boot/dts/zynq-zc702.dts
@@ -28,7 +28,3 @@
28 }; 28 };
29 29
30}; 30};
31
32&ps_clk {
33 clock-frequency = <33333330>;
34};
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index c70969b9c258..50d008d8f87f 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -117,7 +117,7 @@ int __init zynq_slcr_init(void)
117 117
118 pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); 118 pr_info("%s mapped to %p\n", np->name, zynq_slcr_base);
119 119
120 xilinx_zynq_clocks_init(zynq_slcr_base); 120 zynq_clock_init(zynq_slcr_base);
121 121
122 of_node_put(np); 122 of_node_put(np);
123 123
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 137d3e730f86..fa435bcf9f1a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
27obj-$(CONFIG_ARCH_SUNXI) += sunxi/ 27obj-$(CONFIG_ARCH_SUNXI) += sunxi/
28obj-$(CONFIG_ARCH_U8500) += ux500/ 28obj-$(CONFIG_ARCH_U8500) += ux500/
29obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o 29obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
30obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o 30obj-$(CONFIG_ARCH_ZYNQ) += zynq/
31obj-$(CONFIG_ARCH_TEGRA) += tegra/ 31obj-$(CONFIG_ARCH_TEGRA) += tegra/
32obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ 32obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
33 33
diff --git a/drivers/clk/clk-zynq.c b/drivers/clk/clk-zynq.c
deleted file mode 100644
index 32062977f453..000000000000
--- a/drivers/clk/clk-zynq.c
+++ /dev/null
@@ -1,378 +0,0 @@
1/*
2 * Copyright (c) 2012 National Instruments
3 *
4 * Josh Cartwright <josh.cartwright@ni.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/slab.h>
21#include <linux/kernel.h>
22#include <linux/clk-provider.h>
23#include <linux/clk/zynq.h>
24
25static void __iomem *slcr_base;
26
27struct zynq_pll_clk {
28 struct clk_hw hw;
29 void __iomem *pll_ctrl;
30 void __iomem *pll_cfg;
31};
32
33#define to_zynq_pll_clk(hw) container_of(hw, struct zynq_pll_clk, hw)
34
35#define CTRL_PLL_FDIV(x) ((x) >> 12)
36
37static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
38 unsigned long parent_rate)
39{
40 struct zynq_pll_clk *pll = to_zynq_pll_clk(hw);
41 return parent_rate * CTRL_PLL_FDIV(ioread32(pll->pll_ctrl));
42}
43
44static const struct clk_ops zynq_pll_clk_ops = {
45 .recalc_rate = zynq_pll_recalc_rate,
46};
47
48static void __init zynq_pll_clk_setup(struct device_node *np)
49{
50 struct clk_init_data init;
51 struct zynq_pll_clk *pll;
52 const char *parent_name;
53 struct clk *clk;
54 u32 regs[2];
55 int ret;
56
57 ret = of_property_read_u32_array(np, "reg", regs, ARRAY_SIZE(regs));
58 if (WARN_ON(ret))
59 return;
60
61 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
62 if (WARN_ON(!pll))
63 return;
64
65 pll->pll_ctrl = slcr_base + regs[0];
66 pll->pll_cfg = slcr_base + regs[1];
67
68 of_property_read_string(np, "clock-output-names", &init.name);
69
70 init.ops = &zynq_pll_clk_ops;
71 parent_name = of_clk_get_parent_name(np, 0);
72 init.parent_names = &parent_name;
73 init.num_parents = 1;
74
75 pll->hw.init = &init;
76
77 clk = clk_register(NULL, &pll->hw);
78 if (WARN_ON(IS_ERR(clk)))
79 return;
80
81 ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
82 if (WARN_ON(ret))
83 return;
84}
85CLK_OF_DECLARE(zynq_pll, "xlnx,zynq-pll", zynq_pll_clk_setup);
86
87struct zynq_periph_clk {
88 struct clk_hw hw;
89 struct clk_onecell_data onecell_data;
90 struct clk *gates[2];
91 void __iomem *clk_ctrl;
92 spinlock_t clkact_lock;
93};
94
95#define to_zynq_periph_clk(hw) container_of(hw, struct zynq_periph_clk, hw)
96
97static const u8 periph_clk_parent_map[] = {
98 0, 0, 1, 2
99};
100#define PERIPH_CLK_CTRL_SRC(x) (periph_clk_parent_map[((x) & 0x30) >> 4])
101#define PERIPH_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8)
102
103static unsigned long zynq_periph_recalc_rate(struct clk_hw *hw,
104 unsigned long parent_rate)
105{
106 struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
107 return parent_rate / PERIPH_CLK_CTRL_DIV(ioread32(periph->clk_ctrl));
108}
109
110static u8 zynq_periph_get_parent(struct clk_hw *hw)
111{
112 struct zynq_periph_clk *periph = to_zynq_periph_clk(hw);
113 return PERIPH_CLK_CTRL_SRC(ioread32(periph->clk_ctrl));
114}
115
116static const struct clk_ops zynq_periph_clk_ops = {
117 .recalc_rate = zynq_periph_recalc_rate,
118 .get_parent = zynq_periph_get_parent,
119};
120
121static void __init zynq_periph_clk_setup(struct device_node *np)
122{
123 struct zynq_periph_clk *periph;
124 const char *parent_names[3];
125 struct clk_init_data init;
126 int clk_num = 0, err;
127 const char *name;
128 struct clk *clk;
129 u32 reg;
130 int i;
131
132 err = of_property_read_u32(np, "reg", &reg);
133 if (WARN_ON(err))
134 return;
135
136 periph = kzalloc(sizeof(*periph), GFP_KERNEL);
137 if (WARN_ON(!periph))
138 return;
139
140 periph->clk_ctrl = slcr_base + reg;
141 spin_lock_init(&periph->clkact_lock);
142
143 init.name = np->name;
144 init.ops = &zynq_periph_clk_ops;
145 for (i = 0; i < ARRAY_SIZE(parent_names); i++)
146 parent_names[i] = of_clk_get_parent_name(np, i);
147 init.parent_names = parent_names;
148 init.num_parents = ARRAY_SIZE(parent_names);
149
150 periph->hw.init = &init;
151
152 clk = clk_register(NULL, &periph->hw);
153 if (WARN_ON(IS_ERR(clk)))
154 return;
155
156 err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
157 if (WARN_ON(err))
158 return;
159
160 err = of_property_read_string_index(np, "clock-output-names", 0,
161 &name);
162 if (WARN_ON(err))
163 return;
164
165 periph->gates[0] = clk_register_gate(NULL, name, np->name, 0,
166 periph->clk_ctrl, 0, 0,
167 &periph->clkact_lock);
168 if (WARN_ON(IS_ERR(periph->gates[0])))
169 return;
170 clk_num++;
171
172 /* some periph clks have 2 downstream gates */
173 err = of_property_read_string_index(np, "clock-output-names", 1,
174 &name);
175 if (err != -ENODATA) {
176 periph->gates[1] = clk_register_gate(NULL, name, np->name, 0,
177 periph->clk_ctrl, 1, 0,
178 &periph->clkact_lock);
179 if (WARN_ON(IS_ERR(periph->gates[1])))
180 return;
181 clk_num++;
182 }
183
184 periph->onecell_data.clks = periph->gates;
185 periph->onecell_data.clk_num = clk_num;
186
187 err = of_clk_add_provider(np, of_clk_src_onecell_get,
188 &periph->onecell_data);
189 if (WARN_ON(err))
190 return;
191}
192CLK_OF_DECLARE(zynq_periph, "xlnx,zynq-periph-clock", zynq_periph_clk_setup);
193
194/* CPU Clock domain is modelled as a mux with 4 children subclks, whose
195 * derivative rates depend on CLK_621_TRUE
196 */
197
198struct zynq_cpu_clk {
199 struct clk_hw hw;
200 struct clk_onecell_data onecell_data;
201 struct clk *subclks[4];
202 void __iomem *clk_ctrl;
203 spinlock_t clkact_lock;
204};
205
206#define to_zynq_cpu_clk(hw) container_of(hw, struct zynq_cpu_clk, hw)
207
208static const u8 zynq_cpu_clk_parent_map[] = {
209 1, 1, 2, 0
210};
211#define CPU_CLK_SRCSEL(x) (zynq_cpu_clk_parent_map[(((x) & 0x30) >> 4)])
212#define CPU_CLK_CTRL_DIV(x) (((x) & 0x3F00) >> 8)
213
214static u8 zynq_cpu_clk_get_parent(struct clk_hw *hw)
215{
216 struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
217 return CPU_CLK_SRCSEL(ioread32(cpuclk->clk_ctrl));
218}
219
220static unsigned long zynq_cpu_clk_recalc_rate(struct clk_hw *hw,
221 unsigned long parent_rate)
222{
223 struct zynq_cpu_clk *cpuclk = to_zynq_cpu_clk(hw);
224 return parent_rate / CPU_CLK_CTRL_DIV(ioread32(cpuclk->clk_ctrl));
225}
226
227static const struct clk_ops zynq_cpu_clk_ops = {
228 .get_parent = zynq_cpu_clk_get_parent,
229 .recalc_rate = zynq_cpu_clk_recalc_rate,
230};
231
232struct zynq_cpu_subclk {
233 struct clk_hw hw;
234 void __iomem *clk_621;
235 enum {
236 CPU_SUBCLK_6X4X,
237 CPU_SUBCLK_3X2X,
238 CPU_SUBCLK_2X,
239 CPU_SUBCLK_1X,
240 } which;
241};
242
243#define CLK_621_TRUE(x) ((x) & 1)
244
245#define to_zynq_cpu_subclk(hw) container_of(hw, struct zynq_cpu_subclk, hw);
246
247static unsigned long zynq_cpu_subclk_recalc_rate(struct clk_hw *hw,
248 unsigned long parent_rate)
249{
250 unsigned long uninitialized_var(rate);
251 struct zynq_cpu_subclk *subclk;
252 bool is_621;
253
254 subclk = to_zynq_cpu_subclk(hw)
255 is_621 = CLK_621_TRUE(ioread32(subclk->clk_621));
256
257 switch (subclk->which) {
258 case CPU_SUBCLK_6X4X:
259 rate = parent_rate;
260 break;
261 case CPU_SUBCLK_3X2X:
262 rate = parent_rate / 2;
263 break;
264 case CPU_SUBCLK_2X:
265 rate = parent_rate / (is_621 ? 3 : 2);
266 break;
267 case CPU_SUBCLK_1X:
268 rate = parent_rate / (is_621 ? 6 : 4);
269 break;
270 };
271
272 return rate;
273}
274
275static const struct clk_ops zynq_cpu_subclk_ops = {
276 .recalc_rate = zynq_cpu_subclk_recalc_rate,
277};
278
279static struct clk *zynq_cpu_subclk_setup(struct device_node *np, u8 which,
280 void __iomem *clk_621)
281{
282 struct zynq_cpu_subclk *subclk;
283 struct clk_init_data init;
284 struct clk *clk;
285 int err;
286
287 err = of_property_read_string_index(np, "clock-output-names",
288 which, &init.name);
289 if (WARN_ON(err))
290 goto err_read_output_name;
291
292 subclk = kzalloc(sizeof(*subclk), GFP_KERNEL);
293 if (!subclk)
294 goto err_subclk_alloc;
295
296 subclk->clk_621 = clk_621;
297 subclk->which = which;
298
299 init.ops = &zynq_cpu_subclk_ops;
300 init.parent_names = &np->name;
301 init.num_parents = 1;
302
303 subclk->hw.init = &init;
304
305 clk = clk_register(NULL, &subclk->hw);
306 if (WARN_ON(IS_ERR(clk)))
307 goto err_clk_register;
308
309 return clk;
310
311err_clk_register:
312 kfree(subclk);
313err_subclk_alloc:
314err_read_output_name:
315 return ERR_PTR(-EINVAL);
316}
317
318static void __init zynq_cpu_clk_setup(struct device_node *np)
319{
320 struct zynq_cpu_clk *cpuclk;
321 const char *parent_names[3];
322 struct clk_init_data init;
323 void __iomem *clk_621;
324 struct clk *clk;
325 u32 reg[2];
326 int err;
327 int i;
328
329 err = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
330 if (WARN_ON(err))
331 return;
332
333 cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
334 if (WARN_ON(!cpuclk))
335 return;
336
337 cpuclk->clk_ctrl = slcr_base + reg[0];
338 clk_621 = slcr_base + reg[1];
339 spin_lock_init(&cpuclk->clkact_lock);
340
341 init.name = np->name;
342 init.ops = &zynq_cpu_clk_ops;
343 for (i = 0; i < ARRAY_SIZE(parent_names); i++)
344 parent_names[i] = of_clk_get_parent_name(np, i);
345 init.parent_names = parent_names;
346 init.num_parents = ARRAY_SIZE(parent_names);
347
348 cpuclk->hw.init = &init;
349
350 clk = clk_register(NULL, &cpuclk->hw);
351 if (WARN_ON(IS_ERR(clk)))
352 return;
353
354 err = of_clk_add_provider(np, of_clk_src_simple_get, clk);
355 if (WARN_ON(err))
356 return;
357
358 for (i = 0; i < 4; i++) {
359 cpuclk->subclks[i] = zynq_cpu_subclk_setup(np, i, clk_621);
360 if (WARN_ON(IS_ERR(cpuclk->subclks[i])))
361 return;
362 }
363
364 cpuclk->onecell_data.clks = cpuclk->subclks;
365 cpuclk->onecell_data.clk_num = i;
366
367 err = of_clk_add_provider(np, of_clk_src_onecell_get,
368 &cpuclk->onecell_data);
369 if (WARN_ON(err))
370 return;
371}
372CLK_OF_DECLARE(zynq_cpu, "xlnx,zynq-cpu-clock", zynq_cpu_clk_setup);
373
374void __init xilinx_zynq_clocks_init(void __iomem *slcr)
375{
376 slcr_base = slcr;
377 of_clk_init(NULL);
378}
diff --git a/drivers/clk/zynq/Makefile b/drivers/clk/zynq/Makefile
new file mode 100644
index 000000000000..156d923f4fa9
--- /dev/null
+++ b/drivers/clk/zynq/Makefile
@@ -0,0 +1,3 @@
1# Zynq clock specific Makefile
2
3obj-$(CONFIG_ARCH_ZYNQ) += clkc.o pll.o
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
new file mode 100644
index 000000000000..5c205b60a82a
--- /dev/null
+++ b/drivers/clk/zynq/clkc.c
@@ -0,0 +1,533 @@
1/*
2 * Zynq clock controller
3 *
4 * Copyright (C) 2012 - 2013 Xilinx
5 *
6 * Sören Brinkmann <soren.brinkmann@xilinx.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License v2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <linux/clk/zynq.h>
22#include <linux/clk-provider.h>
23#include <linux/of.h>
24#include <linux/slab.h>
25#include <linux/string.h>
26#include <linux/io.h>
27
28static void __iomem *zynq_slcr_base_priv;
29
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)
52
53#define NUM_MIO_PINS 54
54
55enum zynq_clk {
56 armpll, ddrpll, iopll,
57 cpu_6or4x, cpu_3or2x, cpu_2x, cpu_1x,
58 ddr2x, ddr3x, dci,
59 lqspi, smc, pcap, gem0, gem1, fclk0, fclk1, fclk2, fclk3, can0, can1,
60 sdio0, sdio1, uart0, uart1, spi0, spi1, dma,
61 usb0_aper, usb1_aper, gem0_aper, gem1_aper,
62 sdio0_aper, sdio1_aper, spi0_aper, spi1_aper, can0_aper, can1_aper,
63 i2c0_aper, i2c1_aper, uart0_aper, uart1_aper, gpio_aper, lqspi_aper,
64 smc_aper, swdt, dbg_trc, dbg_apb, clk_max};
65
66static struct clk *ps_clk;
67static struct clk *clks[clk_max];
68static struct clk_onecell_data clk_data;
69
70static DEFINE_SPINLOCK(armpll_lock);
71static DEFINE_SPINLOCK(ddrpll_lock);
72static DEFINE_SPINLOCK(iopll_lock);
73static DEFINE_SPINLOCK(armclk_lock);
74static DEFINE_SPINLOCK(ddrclk_lock);
75static DEFINE_SPINLOCK(dciclk_lock);
76static DEFINE_SPINLOCK(gem0clk_lock);
77static DEFINE_SPINLOCK(gem1clk_lock);
78static DEFINE_SPINLOCK(canclk_lock);
79static DEFINE_SPINLOCK(canmioclk_lock);
80static DEFINE_SPINLOCK(dbgclk_lock);
81static DEFINE_SPINLOCK(aperclk_lock);
82
83static const char dummy_nm[] __initconst = "dummy_name";
84
85static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"};
86static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"};
87static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"};
88static const char *gem0_mux_parents[] __initdata = {"gem0_div1", dummy_nm};
89static const char *gem1_mux_parents[] __initdata = {"gem1_div1", dummy_nm};
90static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate",
91 "can0_mio_mux"};
92static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate",
93 "can1_mio_mux"};
94static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div",
95 dummy_nm};
96
97static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"};
98static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"};
99static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"};
100static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"};
101
102static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
103 const char *clk_name, void __iomem *fclk_ctrl_reg,
104 const char **parents)
105{
106 struct clk *clk;
107 char *mux_name;
108 char *div0_name;
109 char *div1_name;
110 spinlock_t *fclk_lock;
111 spinlock_t *fclk_gate_lock;
112 void __iomem *fclk_gate_reg = fclk_ctrl_reg + 8;
113
114 fclk_lock = kmalloc(sizeof(*fclk_lock), GFP_KERNEL);
115 if (!fclk_lock)
116 goto err;
117 fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL);
118 if (!fclk_gate_lock)
119 goto err;
120 spin_lock_init(fclk_lock);
121 spin_lock_init(fclk_gate_lock);
122
123 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
124 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
125 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
126
127 clk = clk_register_mux(NULL, mux_name, parents, 4, 0,
128 fclk_ctrl_reg, 4, 2, 0, fclk_lock);
129
130 clk = clk_register_divider(NULL, div0_name, mux_name,
131 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED |
132 CLK_DIVIDER_ALLOW_ZERO, fclk_lock);
133
134 clk = clk_register_divider(NULL, div1_name, div0_name,
135 CLK_SET_RATE_PARENT, fclk_ctrl_reg, 20, 6,
136 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
137 fclk_lock);
138
139 clks[fclk] = clk_register_gate(NULL, clk_name,
140 div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
141 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
142 kfree(mux_name);
143 kfree(div0_name);
144 kfree(div1_name);
145
146 return;
147
148err:
149 clks[fclk] = ERR_PTR(-ENOMEM);
150}
151
152static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0,
153 enum zynq_clk clk1, const char *clk_name0,
154 const char *clk_name1, void __iomem *clk_ctrl,
155 const char **parents, unsigned int two_gates)
156{
157 struct clk *clk;
158 char *mux_name;
159 char *div_name;
160 spinlock_t *lock;
161
162 lock = kmalloc(sizeof(*lock), GFP_KERNEL);
163 if (!lock)
164 goto err;
165 spin_lock_init(lock);
166
167 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0);
168 div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0);
169
170 clk = clk_register_mux(NULL, mux_name, parents, 4, 0,
171 clk_ctrl, 4, 2, 0, lock);
172
173 clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6,
174 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock);
175
176 clks[clk0] = clk_register_gate(NULL, clk_name0, div_name,
177 CLK_SET_RATE_PARENT, clk_ctrl, 0, 0, lock);
178 if (two_gates)
179 clks[clk1] = clk_register_gate(NULL, clk_name1, div_name,
180 CLK_SET_RATE_PARENT, clk_ctrl, 1, 0, lock);
181
182 kfree(mux_name);
183 kfree(div_name);
184
185 return;
186
187err:
188 clks[clk0] = ERR_PTR(-ENOMEM);
189 if (two_gates)
190 clks[clk1] = ERR_PTR(-ENOMEM);
191}
192
193static void __init zynq_clk_setup(struct device_node *np)
194{
195 int i;
196 u32 tmp;
197 int ret;
198 struct clk *clk;
199 char *clk_name;
200 const char *clk_output_name[clk_max];
201 const char *cpu_parents[4];
202 const char *periph_parents[4];
203 const char *swdt_ext_clk_mux_parents[2];
204 const char *can_mio_mux_parents[NUM_MIO_PINS];
205
206 pr_info("Zynq clock init\n");
207
208 /* get clock output names from DT */
209 for (i = 0; i < clk_max; i++) {
210 if (of_property_read_string_index(np, "clock-output-names",
211 i, &clk_output_name[i])) {
212 pr_err("%s: clock output name not in DT\n", __func__);
213 BUG();
214 }
215 }
216 cpu_parents[0] = clk_output_name[armpll];
217 cpu_parents[1] = clk_output_name[armpll];
218 cpu_parents[2] = clk_output_name[ddrpll];
219 cpu_parents[3] = clk_output_name[iopll];
220 periph_parents[0] = clk_output_name[iopll];
221 periph_parents[1] = clk_output_name[iopll];
222 periph_parents[2] = clk_output_name[armpll];
223 periph_parents[3] = clk_output_name[ddrpll];
224
225 /* ps_clk */
226 ret = of_property_read_u32(np, "ps-clk-frequency", &tmp);
227 if (ret) {
228 pr_warn("ps_clk frequency not specified, using 33 MHz.\n");
229 tmp = 33333333;
230 }
231 ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT,
232 tmp);
233
234 /* PLLs */
235 clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL,
236 SLCR_PLL_STATUS, 0, &armpll_lock);
237 clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll],
238 armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0,
239 &armpll_lock);
240
241 clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL,
242 SLCR_PLL_STATUS, 1, &ddrpll_lock);
243 clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll],
244 ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0,
245 &ddrpll_lock);
246
247 clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL,
248 SLCR_PLL_STATUS, 2, &iopll_lock);
249 clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll],
250 iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0,
251 &iopll_lock);
252
253 /* CPU clocks */
254 tmp = readl(SLCR_621_TRUE) & 1;
255 clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0,
256 SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock);
257 clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0,
258 SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
259 CLK_DIVIDER_ALLOW_ZERO, &armclk_lock);
260
261 clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x],
262 "cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
263 SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock);
264
265 clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0,
266 1, 2);
267 clks[cpu_3or2x] = clk_register_gate(NULL, clk_output_name[cpu_3or2x],
268 "cpu_3or2x_div", CLK_IGNORE_UNUSED,
269 SLCR_ARM_CLK_CTRL, 25, 0, &armclk_lock);
270
271 clk = clk_register_fixed_factor(NULL, "cpu_2x_div", "cpu_div", 0, 1,
272 2 + tmp);
273 clks[cpu_2x] = clk_register_gate(NULL, clk_output_name[cpu_2x],
274 "cpu_2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL,
275 26, 0, &armclk_lock);
276
277 clk = clk_register_fixed_factor(NULL, "cpu_1x_div", "cpu_div", 0, 1,
278 4 + 2 * tmp);
279 clks[cpu_1x] = clk_register_gate(NULL, clk_output_name[cpu_1x],
280 "cpu_1x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 27,
281 0, &armclk_lock);
282
283 /* Timers */
284 swdt_ext_clk_mux_parents[0] = clk_output_name[cpu_1x];
285 for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) {
286 int idx = of_property_match_string(np, "clock-names",
287 swdt_ext_clk_input_names[i]);
288 if (idx >= 0)
289 swdt_ext_clk_mux_parents[i + 1] =
290 of_clk_get_parent_name(np, idx);
291 else
292 swdt_ext_clk_mux_parents[i + 1] = dummy_nm;
293 }
294 clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt],
295 swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT,
296 SLCR_SWDT_CLK_SEL, 0, 1, 0, &gem0clk_lock);
297
298 /* DDR clocks */
299 clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0,
300 SLCR_DDR_CLK_CTRL, 26, 6, CLK_DIVIDER_ONE_BASED |
301 CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
302 clks[ddr2x] = clk_register_gate(NULL, clk_output_name[ddr2x],
303 "ddr2x_div", 0, SLCR_DDR_CLK_CTRL, 1, 0, &ddrclk_lock);
304 clk_prepare_enable(clks[ddr2x]);
305 clk = clk_register_divider(NULL, "ddr3x_div", "ddrpll", 0,
306 SLCR_DDR_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED |
307 CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock);
308 clks[ddr3x] = clk_register_gate(NULL, clk_output_name[ddr3x],
309 "ddr3x_div", 0, SLCR_DDR_CLK_CTRL, 0, 0, &ddrclk_lock);
310 clk_prepare_enable(clks[ddr3x]);
311
312 clk = clk_register_divider(NULL, "dci_div0", "ddrpll", 0,
313 SLCR_DCI_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
314 CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock);
315 clk = clk_register_divider(NULL, "dci_div1", "dci_div0",
316 CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 20, 6,
317 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
318 &dciclk_lock);
319 clks[dci] = clk_register_gate(NULL, clk_output_name[dci], "dci_div1",
320 CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 0, 0,
321 &dciclk_lock);
322 clk_prepare_enable(clks[dci]);
323
324 /* Peripheral clocks */
325 for (i = fclk0; i <= fclk3; i++)
326 zynq_clk_register_fclk(i, clk_output_name[i],
327 SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0),
328 periph_parents);
329
330 zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL,
331 SLCR_LQSPI_CLK_CTRL, periph_parents, 0);
332
333 zynq_clk_register_periph_clk(smc, 0, clk_output_name[smc], NULL,
334 SLCR_SMC_CLK_CTRL, periph_parents, 0);
335
336 zynq_clk_register_periph_clk(pcap, 0, clk_output_name[pcap], NULL,
337 SLCR_PCAP_CLK_CTRL, periph_parents, 0);
338
339 zynq_clk_register_periph_clk(sdio0, sdio1, clk_output_name[sdio0],
340 clk_output_name[sdio1], SLCR_SDIO_CLK_CTRL,
341 periph_parents, 1);
342
343 zynq_clk_register_periph_clk(uart0, uart1, clk_output_name[uart0],
344 clk_output_name[uart1], SLCR_UART_CLK_CTRL,
345 periph_parents, 1);
346
347 zynq_clk_register_periph_clk(spi0, spi1, clk_output_name[spi0],
348 clk_output_name[spi1], SLCR_SPI_CLK_CTRL,
349 periph_parents, 1);
350
351 for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) {
352 int idx = of_property_match_string(np, "clock-names",
353 gem0_emio_input_names[i]);
354 if (idx >= 0)
355 gem0_mux_parents[i + 1] = of_clk_get_parent_name(np,
356 idx);
357 }
358 clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0,
359 SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock);
360 clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0,
361 SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
362 CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock);
363 clk = clk_register_divider(NULL, "gem0_div1", "gem0_div0",
364 CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6,
365 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
366 &gem0clk_lock);
367 clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, 0,
368 SLCR_GEM0_CLK_CTRL, 6, 1, 0, &gem0clk_lock);
369 clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0],
370 "gem0_emio_mux", CLK_SET_RATE_PARENT,
371 SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock);
372
373 for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) {
374 int idx = of_property_match_string(np, "clock-names",
375 gem1_emio_input_names[i]);
376 if (idx >= 0)
377 gem1_mux_parents[i + 1] = of_clk_get_parent_name(np,
378 idx);
379 }
380 clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0,
381 SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock);
382 clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0,
383 SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
384 CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock);
385 clk = clk_register_divider(NULL, "gem1_div1", "gem1_div0",
386 CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6,
387 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
388 &gem1clk_lock);
389 clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, 0,
390 SLCR_GEM1_CLK_CTRL, 6, 1, 0, &gem1clk_lock);
391 clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1],
392 "gem1_emio_mux", CLK_SET_RATE_PARENT,
393 SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
394
395 tmp = strlen("mio_clk_00x");
396 clk_name = kmalloc(tmp, GFP_KERNEL);
397 for (i = 0; i < NUM_MIO_PINS; i++) {
398 int idx;
399
400 snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
401 idx = of_property_match_string(np, "clock-names", clk_name);
402 if (idx >= 0)
403 can_mio_mux_parents[i] = of_clk_get_parent_name(np,
404 idx);
405 else
406 can_mio_mux_parents[i] = dummy_nm;
407 }
408 kfree(clk_name);
409 clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0,
410 SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock);
411 clk = clk_register_divider(NULL, "can_div0", "can_mux", 0,
412 SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
413 CLK_DIVIDER_ALLOW_ZERO, &canclk_lock);
414 clk = clk_register_divider(NULL, "can_div1", "can_div0",
415 CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 20, 6,
416 CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
417 &canclk_lock);
418 clk = clk_register_gate(NULL, "can0_gate", "can_div1",
419 CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 0, 0,
420 &canclk_lock);
421 clk = clk_register_gate(NULL, "can1_gate", "can_div1",
422 CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0,
423 &canclk_lock);
424 clk = clk_register_mux(NULL, "can0_mio_mux",
425 can_mio_mux_parents, 54, CLK_SET_RATE_PARENT,
426 SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock);
427 clk = clk_register_mux(NULL, "can1_mio_mux",
428 can_mio_mux_parents, 54, CLK_SET_RATE_PARENT,
429 SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock);
430 clks[can0] = clk_register_mux(NULL, clk_output_name[can0],
431 can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT,
432 SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock);
433 clks[can1] = clk_register_mux(NULL, clk_output_name[can1],
434 can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT,
435 SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock);
436
437 for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) {
438 int idx = of_property_match_string(np, "clock-names",
439 dbgtrc_emio_input_names[i]);
440 if (idx >= 0)
441 dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np,
442 idx);
443 }
444 clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0,
445 SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock);
446 clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0,
447 SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED |
448 CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock);
449 clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0,
450 SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock);
451 clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc],
452 "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL,
453 0, 0, &dbgclk_lock);
454 clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb],
455 clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0,
456 &dbgclk_lock);
457
458 /* One gated clock for all APER clocks. */
459 clks[dma] = clk_register_gate(NULL, clk_output_name[dma],
460 clk_output_name[cpu_2x], 0, SLCR_APER_CLK_CTRL, 0, 0,
461 &aperclk_lock);
462 clks[usb0_aper] = clk_register_gate(NULL, clk_output_name[usb0_aper],
463 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 2, 0,
464 &aperclk_lock);
465 clks[usb1_aper] = clk_register_gate(NULL, clk_output_name[usb1_aper],
466 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 3, 0,
467 &aperclk_lock);
468 clks[gem0_aper] = clk_register_gate(NULL, clk_output_name[gem0_aper],
469 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 6, 0,
470 &aperclk_lock);
471 clks[gem1_aper] = clk_register_gate(NULL, clk_output_name[gem1_aper],
472 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 7, 0,
473 &aperclk_lock);
474 clks[sdio0_aper] = clk_register_gate(NULL, clk_output_name[sdio0_aper],
475 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 10, 0,
476 &aperclk_lock);
477 clks[sdio1_aper] = clk_register_gate(NULL, clk_output_name[sdio1_aper],
478 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 11, 0,
479 &aperclk_lock);
480 clks[spi0_aper] = clk_register_gate(NULL, clk_output_name[spi0_aper],
481 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 14, 0,
482 &aperclk_lock);
483 clks[spi1_aper] = clk_register_gate(NULL, clk_output_name[spi1_aper],
484 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 15, 0,
485 &aperclk_lock);
486 clks[can0_aper] = clk_register_gate(NULL, clk_output_name[can0_aper],
487 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 16, 0,
488 &aperclk_lock);
489 clks[can1_aper] = clk_register_gate(NULL, clk_output_name[can1_aper],
490 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 17, 0,
491 &aperclk_lock);
492 clks[i2c0_aper] = clk_register_gate(NULL, clk_output_name[i2c0_aper],
493 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 18, 0,
494 &aperclk_lock);
495 clks[i2c1_aper] = clk_register_gate(NULL, clk_output_name[i2c1_aper],
496 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 19, 0,
497 &aperclk_lock);
498 clks[uart0_aper] = clk_register_gate(NULL, clk_output_name[uart0_aper],
499 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 20, 0,
500 &aperclk_lock);
501 clks[uart1_aper] = clk_register_gate(NULL, clk_output_name[uart1_aper],
502 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 21, 0,
503 &aperclk_lock);
504 clks[gpio_aper] = clk_register_gate(NULL, clk_output_name[gpio_aper],
505 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 22, 0,
506 &aperclk_lock);
507 clks[lqspi_aper] = clk_register_gate(NULL, clk_output_name[lqspi_aper],
508 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 23, 0,
509 &aperclk_lock);
510 clks[smc_aper] = clk_register_gate(NULL, clk_output_name[smc_aper],
511 clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 24, 0,
512 &aperclk_lock);
513
514 for (i = 0; i < ARRAY_SIZE(clks); i++) {
515 if (IS_ERR(clks[i])) {
516 pr_err("Zynq clk %d: register failed with %ld\n",
517 i, PTR_ERR(clks[i]));
518 BUG();
519 }
520 }
521
522 clk_data.clks = clks;
523 clk_data.clk_num = ARRAY_SIZE(clks);
524 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
525}
526
527CLK_OF_DECLARE(zynq_clkc, "xlnx,ps7-clkc", zynq_clk_setup);
528
529void __init zynq_clock_init(void __iomem *slcr_base)
530{
531 zynq_slcr_base_priv = slcr_base;
532 of_clk_init(NULL);
533}
diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
new file mode 100644
index 000000000000..47e307c25a7b
--- /dev/null
+++ b/drivers/clk/zynq/pll.c
@@ -0,0 +1,235 @@
1/*
2 * Zynq PLL driver
3 *
4 * Copyright (C) 2013 Xilinx
5 *
6 * Sören Brinkmann <soren.brinkmann@xilinx.com>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License v2 as published by
10 * the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21#include <linux/clk/zynq.h>
22#include <linux/clk-provider.h>
23#include <linux/slab.h>
24#include <linux/io.h>
25
26/**
27 * struct zynq_pll
28 * @hw: Handle between common and hardware-specific interfaces
29 * @pll_ctrl: PLL control register
30 * @pll_status: PLL status register
31 * @lock: Register lock
32 * @lockbit: Indicates the associated PLL_LOCKED bit in the PLL status
33 * register.
34 */
35struct zynq_pll {
36 struct clk_hw hw;
37 void __iomem *pll_ctrl;
38 void __iomem *pll_status;
39 spinlock_t *lock;
40 u8 lockbit;
41};
42#define to_zynq_pll(_hw) container_of(_hw, struct zynq_pll, hw)
43
44/* Register bitfield defines */
45#define PLLCTRL_FBDIV_MASK 0x7f000
46#define PLLCTRL_FBDIV_SHIFT 12
47#define PLLCTRL_BPQUAL_MASK (1 << 3)
48#define PLLCTRL_PWRDWN_MASK 2
49#define PLLCTRL_PWRDWN_SHIFT 1
50#define PLLCTRL_RESET_MASK 1
51#define PLLCTRL_RESET_SHIFT 0
52
53/**
54 * zynq_pll_round_rate() - Round a clock frequency
55 * @hw: Handle between common and hardware-specific interfaces
56 * @rate: Desired clock frequency
57 * @prate: Clock frequency of parent clock
58 * Returns frequency closest to @rate the hardware can generate.
59 */
60static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate,
61 unsigned long *prate)
62{
63 u32 fbdiv;
64
65 fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
66 if (fbdiv < 13)
67 fbdiv = 13;
68 else if (fbdiv > 66)
69 fbdiv = 66;
70
71 return *prate * fbdiv;
72}
73
74/**
75 * zynq_pll_recalc_rate() - Recalculate clock frequency
76 * @hw: Handle between common and hardware-specific interfaces
77 * @parent_rate: Clock frequency of parent clock
78 * Returns current clock frequency.
79 */
80static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
81 unsigned long parent_rate)
82{
83 struct zynq_pll *clk = to_zynq_pll(hw);
84 u32 fbdiv;
85
86 /*
87 * makes probably sense to redundantly save fbdiv in the struct
88 * zynq_pll to save the IO access.
89 */
90 fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
91 PLLCTRL_FBDIV_SHIFT;
92
93 return parent_rate * fbdiv;
94}
95
96/**
97 * zynq_pll_is_enabled - Check if a clock is enabled
98 * @hw: Handle between common and hardware-specific interfaces
99 * Returns 1 if the clock is enabled, 0 otherwise.
100 *
101 * Not sure this is a good idea, but since disabled means bypassed for
102 * this clock implementation we say we are always enabled.
103 */
104static int zynq_pll_is_enabled(struct clk_hw *hw)
105{
106 unsigned long flags = 0;
107 u32 reg;
108 struct zynq_pll *clk = to_zynq_pll(hw);
109
110 spin_lock_irqsave(clk->lock, flags);
111
112 reg = readl(clk->pll_ctrl);
113
114 spin_unlock_irqrestore(clk->lock, flags);
115
116 return !(reg & (PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK));
117}
118
119/**
120 * zynq_pll_enable - Enable clock
121 * @hw: Handle between common and hardware-specific interfaces
122 * Returns 0 on success
123 */
124static int zynq_pll_enable(struct clk_hw *hw)
125{
126 unsigned long flags = 0;
127 u32 reg;
128 struct zynq_pll *clk = to_zynq_pll(hw);
129
130 if (zynq_pll_is_enabled(hw))
131 return 0;
132
133 pr_info("PLL: enable\n");
134
135 /* Power up PLL and wait for lock */
136 spin_lock_irqsave(clk->lock, flags);
137
138 reg = readl(clk->pll_ctrl);
139 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
140 writel(reg, clk->pll_ctrl);
141 while (!(readl(clk->pll_status) & (1 << clk->lockbit)))
142 ;
143
144 spin_unlock_irqrestore(clk->lock, flags);
145
146 return 0;
147}
148
149/**
150 * zynq_pll_disable - Disable clock
151 * @hw: Handle between common and hardware-specific interfaces
152 * Returns 0 on success
153 */
154static void zynq_pll_disable(struct clk_hw *hw)
155{
156 unsigned long flags = 0;
157 u32 reg;
158 struct zynq_pll *clk = to_zynq_pll(hw);
159
160 if (!zynq_pll_is_enabled(hw))
161 return;
162
163 pr_info("PLL: shutdown\n");
164
165 /* shut down PLL */
166 spin_lock_irqsave(clk->lock, flags);
167
168 reg = readl(clk->pll_ctrl);
169 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
170 writel(reg, clk->pll_ctrl);
171
172 spin_unlock_irqrestore(clk->lock, flags);
173}
174
175static const struct clk_ops zynq_pll_ops = {
176 .enable = zynq_pll_enable,
177 .disable = zynq_pll_disable,
178 .is_enabled = zynq_pll_is_enabled,
179 .round_rate = zynq_pll_round_rate,
180 .recalc_rate = zynq_pll_recalc_rate
181};
182
183/**
184 * clk_register_zynq_pll() - Register PLL with the clock framework
185 * @np Pointer to the DT device node
186 */
187struct clk *clk_register_zynq_pll(const char *name, const char *parent,
188 void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
189 spinlock_t *lock)
190{
191 struct zynq_pll *pll;
192 struct clk *clk;
193 u32 reg;
194 const char *parent_arr[1] = {parent};
195 unsigned long flags = 0;
196 struct clk_init_data initd = {
197 .name = name,
198 .parent_names = parent_arr,
199 .ops = &zynq_pll_ops,
200 .num_parents = 1,
201 .flags = 0
202 };
203
204 pll = kmalloc(sizeof(*pll), GFP_KERNEL);
205 if (!pll) {
206 pr_err("%s: Could not allocate Zynq PLL clk.\n", __func__);
207 return ERR_PTR(-ENOMEM);
208 }
209
210 /* Populate the struct */
211 pll->hw.init = &initd;
212 pll->pll_ctrl = pll_ctrl;
213 pll->pll_status = pll_status;
214 pll->lockbit = lock_index;
215 pll->lock = lock;
216
217 spin_lock_irqsave(pll->lock, flags);
218
219 reg = readl(pll->pll_ctrl);
220 reg &= ~PLLCTRL_BPQUAL_MASK;
221 writel(reg, pll->pll_ctrl);
222
223 spin_unlock_irqrestore(pll->lock, flags);
224
225 clk = clk_register(NULL, &pll->hw);
226 if (WARN_ON(IS_ERR(clk)))
227 goto free_pll;
228
229 return clk;
230
231free_pll:
232 kfree(pll);
233
234 return clk;
235}
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c
index 685bc60e210a..4cbe28c74631 100644
--- a/drivers/clocksource/cadence_ttc_timer.c
+++ b/drivers/clocksource/cadence_ttc_timer.c
@@ -51,6 +51,8 @@
51 51
52#define TTC_CNT_CNTRL_DISABLE_MASK 0x1 52#define TTC_CNT_CNTRL_DISABLE_MASK 0x1
53 53
54#define TTC_CLK_CNTRL_CSRC_MASK (1 << 5) /* clock source */
55
54/* 56/*
55 * Setup the timers to use pre-scaling, using a fixed value for now that will 57 * Setup the timers to use pre-scaling, using a fixed value for now that will
56 * work across most input frequency, but it may need to be more dynamic 58 * work across most input frequency, but it may need to be more dynamic
@@ -396,8 +398,9 @@ static void __init ttc_timer_init(struct device_node *timer)
396{ 398{
397 unsigned int irq; 399 unsigned int irq;
398 void __iomem *timer_baseaddr; 400 void __iomem *timer_baseaddr;
399 struct clk *clk; 401 struct clk *clk_cs, *clk_ce;
400 static int initialized; 402 static int initialized;
403 int clksel;
401 404
402 if (initialized) 405 if (initialized)
403 return; 406 return;
@@ -421,14 +424,24 @@ static void __init ttc_timer_init(struct device_node *timer)
421 BUG(); 424 BUG();
422 } 425 }
423 426
424 clk = of_clk_get_by_name(timer, "cpu_1x"); 427 clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET);
425 if (IS_ERR(clk)) { 428 clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
429 clk_cs = of_clk_get(timer, clksel);
430 if (IS_ERR(clk_cs)) {
431 pr_err("ERROR: timer input clock not found\n");
432 BUG();
433 }
434
435 clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET);
436 clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
437 clk_ce = of_clk_get(timer, clksel);
438 if (IS_ERR(clk_ce)) {
426 pr_err("ERROR: timer input clock not found\n"); 439 pr_err("ERROR: timer input clock not found\n");
427 BUG(); 440 BUG();
428 } 441 }
429 442
430 ttc_setup_clocksource(clk, timer_baseaddr); 443 ttc_setup_clocksource(clk_cs, timer_baseaddr);
431 ttc_setup_clockevent(clk, timer_baseaddr + 4, irq); 444 ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq);
432 445
433 pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq); 446 pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq);
434} 447}
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 4e5c77834c50..a4a3028103e3 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/serial.h> 15#include <linux/serial.h>
16#include <linux/serial_core.h> 16#include <linux/serial_core.h>
17#include <linux/slab.h>
17#include <linux/tty.h> 18#include <linux/tty.h>
18#include <linux/tty_flip.h> 19#include <linux/tty_flip.h>
19#include <linux/console.h> 20#include <linux/console.h>
@@ -139,6 +140,16 @@
139#define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */ 140#define XUARTPS_SR_RXTRIG 0x00000001 /* Rx Trigger */
140 141
141/** 142/**
143 * struct xuartps - device data
144 * @refclk Reference clock
145 * @aperclk APB clock
146 */
147struct xuartps {
148 struct clk *refclk;
149 struct clk *aperclk;
150};
151
152/**
142 * xuartps_isr - Interrupt handler 153 * xuartps_isr - Interrupt handler
143 * @irq: Irq number 154 * @irq: Irq number
144 * @dev_id: Id of the port 155 * @dev_id: Id of the port
@@ -936,34 +947,55 @@ static int xuartps_probe(struct platform_device *pdev)
936 int rc; 947 int rc;
937 struct uart_port *port; 948 struct uart_port *port;
938 struct resource *res, *res2; 949 struct resource *res, *res2;
939 struct clk *clk; 950 struct xuartps *xuartps_data;
940 951
941 clk = of_clk_get(pdev->dev.of_node, 0); 952 xuartps_data = kzalloc(sizeof(*xuartps_data), GFP_KERNEL);
942 if (IS_ERR(clk)) { 953 if (!xuartps_data)
943 dev_err(&pdev->dev, "no clock specified\n"); 954 return -ENOMEM;
944 return PTR_ERR(clk); 955
956 xuartps_data->aperclk = clk_get(&pdev->dev, "aper_clk");
957 if (IS_ERR(xuartps_data->aperclk)) {
958 dev_err(&pdev->dev, "aper_clk clock not found.\n");
959 rc = PTR_ERR(xuartps_data->aperclk);
960 goto err_out_free;
961 }
962 xuartps_data->refclk = clk_get(&pdev->dev, "ref_clk");
963 if (IS_ERR(xuartps_data->refclk)) {
964 dev_err(&pdev->dev, "ref_clk clock not found.\n");
965 rc = PTR_ERR(xuartps_data->refclk);
966 goto err_out_clk_put_aper;
945 } 967 }
946 968
947 rc = clk_prepare_enable(clk); 969 rc = clk_prepare_enable(xuartps_data->aperclk);
970 if (rc) {
971 dev_err(&pdev->dev, "Unable to enable APER clock.\n");
972 goto err_out_clk_put;
973 }
974 rc = clk_prepare_enable(xuartps_data->refclk);
948 if (rc) { 975 if (rc) {
949 dev_err(&pdev->dev, "could not enable clock\n"); 976 dev_err(&pdev->dev, "Unable to enable device clock.\n");
950 return -EBUSY; 977 goto err_out_clk_dis_aper;
951 } 978 }
952 979
953 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 980 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
954 if (!res) 981 if (!res) {
955 return -ENODEV; 982 rc = -ENODEV;
983 goto err_out_clk_disable;
984 }
956 985
957 res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 986 res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
958 if (!res2) 987 if (!res2) {
959 return -ENODEV; 988 rc = -ENODEV;
989 goto err_out_clk_disable;
990 }
960 991
961 /* Initialize the port structure */ 992 /* Initialize the port structure */
962 port = xuartps_get_port(); 993 port = xuartps_get_port();
963 994
964 if (!port) { 995 if (!port) {
965 dev_err(&pdev->dev, "Cannot get uart_port structure\n"); 996 dev_err(&pdev->dev, "Cannot get uart_port structure\n");
966 return -ENODEV; 997 rc = -ENODEV;
998 goto err_out_clk_disable;
967 } else { 999 } else {
968 /* Register the port. 1000 /* Register the port.
969 * This function also registers this device with the tty layer 1001 * This function also registers this device with the tty layer
@@ -972,18 +1004,31 @@ static int xuartps_probe(struct platform_device *pdev)
972 port->mapbase = res->start; 1004 port->mapbase = res->start;
973 port->irq = res2->start; 1005 port->irq = res2->start;
974 port->dev = &pdev->dev; 1006 port->dev = &pdev->dev;
975 port->uartclk = clk_get_rate(clk); 1007 port->uartclk = clk_get_rate(xuartps_data->refclk);
976 port->private_data = clk; 1008 port->private_data = xuartps_data;
977 dev_set_drvdata(&pdev->dev, port); 1009 dev_set_drvdata(&pdev->dev, port);
978 rc = uart_add_one_port(&xuartps_uart_driver, port); 1010 rc = uart_add_one_port(&xuartps_uart_driver, port);
979 if (rc) { 1011 if (rc) {
980 dev_err(&pdev->dev, 1012 dev_err(&pdev->dev,
981 "uart_add_one_port() failed; err=%i\n", rc); 1013 "uart_add_one_port() failed; err=%i\n", rc);
982 dev_set_drvdata(&pdev->dev, NULL); 1014 dev_set_drvdata(&pdev->dev, NULL);
983 return rc; 1015 goto err_out_clk_disable;
984 } 1016 }
985 return 0; 1017 return 0;
986 } 1018 }
1019
1020err_out_clk_disable:
1021 clk_disable_unprepare(xuartps_data->refclk);
1022err_out_clk_dis_aper:
1023 clk_disable_unprepare(xuartps_data->aperclk);
1024err_out_clk_put:
1025 clk_put(xuartps_data->refclk);
1026err_out_clk_put_aper:
1027 clk_put(xuartps_data->aperclk);
1028err_out_free:
1029 kfree(xuartps_data);
1030
1031 return rc;
987} 1032}
988 1033
989/** 1034/**
@@ -995,14 +1040,18 @@ static int xuartps_probe(struct platform_device *pdev)
995static int xuartps_remove(struct platform_device *pdev) 1040static int xuartps_remove(struct platform_device *pdev)
996{ 1041{
997 struct uart_port *port = dev_get_drvdata(&pdev->dev); 1042 struct uart_port *port = dev_get_drvdata(&pdev->dev);
998 struct clk *clk = port->private_data; 1043 struct xuartps *xuartps_data = port->private_data;
999 int rc; 1044 int rc;
1000 1045
1001 /* Remove the xuartps port from the serial core */ 1046 /* Remove the xuartps port from the serial core */
1002 rc = uart_remove_one_port(&xuartps_uart_driver, port); 1047 rc = uart_remove_one_port(&xuartps_uart_driver, port);
1003 dev_set_drvdata(&pdev->dev, NULL); 1048 dev_set_drvdata(&pdev->dev, NULL);
1004 port->mapbase = 0; 1049 port->mapbase = 0;
1005 clk_disable_unprepare(clk); 1050 clk_disable_unprepare(xuartps_data->refclk);
1051 clk_disable_unprepare(xuartps_data->aperclk);
1052 clk_put(xuartps_data->refclk);
1053 clk_put(xuartps_data->aperclk);
1054 kfree(xuartps_data);
1006 return rc; 1055 return rc;
1007} 1056}
1008 1057
diff --git a/include/linux/clk/zynq.h b/include/linux/clk/zynq.h
index 56be7cd9aa8b..e062d317ccce 100644
--- a/include/linux/clk/zynq.h
+++ b/include/linux/clk/zynq.h
@@ -1,4 +1,5 @@
1/* 1/*
2 * Copyright (C) 2013 Xilinx Inc.
2 * Copyright (C) 2012 National Instruments 3 * Copyright (C) 2012 National Instruments
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
@@ -19,6 +20,11 @@
19#ifndef __LINUX_CLK_ZYNQ_H_ 20#ifndef __LINUX_CLK_ZYNQ_H_
20#define __LINUX_CLK_ZYNQ_H_ 21#define __LINUX_CLK_ZYNQ_H_
21 22
22void __init xilinx_zynq_clocks_init(void __iomem *slcr); 23#include <linux/spinlock.h>
23 24
25void zynq_clock_init(void __iomem *slcr);
26
27struct clk *clk_register_zynq_pll(const char *name, const char *parent,
28 void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index,
29 spinlock_t *lock);
24#endif 30#endif