aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-12 02:11:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-12 02:11:47 -0500
commit2b684c073f32b557661eba191ce0a584020367e2 (patch)
tree3d3694ce794236fd28e12ee27689c4c4e2720e98 /drivers/clk
parentc2d33069915d1f9b3b1dcc2199af11d4e072b037 (diff)
parent9ed9c07d9b7d42fc7042247c2be283731186464f (diff)
Merge tag 'clk-for-linus-3.13' of git://git.linaro.org/people/mturquette/linux
Pull clock framework changes from Mike Turquette: "The clock changes for 3.13 are an even mix of framework improvements & bug fixes along with updates to existing clock drivers and the additional of new clock drivers" * tag 'clk-for-linus-3.13' of git://git.linaro.org/people/mturquette/linux: clk: new driver for efm32 SoC clk: of: helper for determining number of parent clocks clk/zynq: Fix possible memory leak clk: keystone: Build Keystone clock drivers clk: keystone: Add gate control clock driver clk: keystone: add Keystone PLL clock driver Documentation: Add documentation for APM X-Gene clock binding clk: arm64: Add DTS clock entry for APM X-Gene Storm SoC clk: Add APM X-Gene SoC clock driver clk: wm831x: get rid of the implementation of remove function clk: Correct lookup logic in clk_fetch_parent_index() clk: Use kcalloc() to allocate arrays clk: Add error handling to clk_fetch_parent_index()
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Kconfig14
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/clk-efm32gg.c81
-rw-r--r--drivers/clk/clk-wm831x.c6
-rw-r--r--drivers/clk/clk-xgene.c521
-rw-r--r--drivers/clk/clk.c56
-rw-r--r--drivers/clk/keystone/Makefile1
-rw-r--r--drivers/clk/keystone/gate.c264
-rw-r--r--drivers/clk/keystone/pll.c305
-rw-r--r--drivers/clk/zynq/clkc.c16
10 files changed, 1238 insertions, 29 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 279407a36391..5c51115081b3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -93,6 +93,20 @@ config CLK_PPC_CORENET
93 This adds the clock driver support for Freescale PowerPC corenet 93 This adds the clock driver support for Freescale PowerPC corenet
94 platforms using common clock framework. 94 platforms using common clock framework.
95 95
96config COMMON_CLK_XGENE
97 bool "Clock driver for APM XGene SoC"
98 default y
99 depends on ARM64
100 ---help---
101 Sypport for the APM X-Gene SoC reference, PLL, and device clocks.
102
103config COMMON_CLK_KEYSTONE
104 tristate "Clock drivers for Keystone based SOCs"
105 depends on ARCH_KEYSTONE && OF
106 ---help---
107 Supports clock drivers for Keystone based SOCs. These SOCs have local
108 a power sleep control module that gate the clock to the IPs and PLLs.
109
96endmenu 110endmenu
97 111
98source "drivers/clk/mvebu/Kconfig" 112source "drivers/clk/mvebu/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 7b111062ccba..7a10bc9a23e7 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-composite.o
11 11
12# SoCs specific 12# SoCs specific
13obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o 13obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
14obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
14obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 15obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
15obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 16obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
16obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 17obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
@@ -32,6 +33,8 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
32obj-$(CONFIG_ARCH_ZYNQ) += zynq/ 33obj-$(CONFIG_ARCH_ZYNQ) += zynq/
33obj-$(CONFIG_ARCH_TEGRA) += tegra/ 34obj-$(CONFIG_ARCH_TEGRA) += tegra/
34obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ 35obj-$(CONFIG_PLAT_SAMSUNG) += samsung/
36obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
37obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/
35 38
36obj-$(CONFIG_X86) += x86/ 39obj-$(CONFIG_X86) += x86/
37 40
diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c
new file mode 100644
index 000000000000..bac2ddf49d02
--- /dev/null
+++ b/drivers/clk/clk-efm32gg.c
@@ -0,0 +1,81 @@
1/*
2 * Copyright (C) 2013 Pengutronix
3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9#include <linux/clk.h>
10#include <linux/io.h>
11#include <linux/clk-provider.h>
12#include <linux/of.h>
13#include <linux/of_address.h>
14
15#include <dt-bindings/clock/efm32-cmu.h>
16
17#define CMU_HFPERCLKEN0 0x44
18
19static struct clk *clk[37];
20static struct clk_onecell_data clk_data = {
21 .clks = clk,
22 .clk_num = ARRAY_SIZE(clk),
23};
24
25static int __init efm32gg_cmu_init(struct device_node *np)
26{
27 int i;
28 void __iomem *base;
29
30 for (i = 0; i < ARRAY_SIZE(clk); ++i)
31 clk[i] = ERR_PTR(-ENOENT);
32
33 base = of_iomap(np, 0);
34 if (!base) {
35 pr_warn("Failed to map address range for efm32gg,cmu node\n");
36 return -EADDRNOTAVAIL;
37 }
38
39 clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL,
40 CLK_IS_ROOT, 48000000);
41
42 clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0",
43 "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
44 clk[clk_HFPERCLKUSART1] = clk_register_gate(NULL, "HFPERCLK.USART1",
45 "HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL);
46 clk[clk_HFPERCLKUSART2] = clk_register_gate(NULL, "HFPERCLK.USART2",
47 "HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL);
48 clk[clk_HFPERCLKUART0] = clk_register_gate(NULL, "HFPERCLK.UART0",
49 "HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL);
50 clk[clk_HFPERCLKUART1] = clk_register_gate(NULL, "HFPERCLK.UART1",
51 "HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL);
52 clk[clk_HFPERCLKTIMER0] = clk_register_gate(NULL, "HFPERCLK.TIMER0",
53 "HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL);
54 clk[clk_HFPERCLKTIMER1] = clk_register_gate(NULL, "HFPERCLK.TIMER1",
55 "HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL);
56 clk[clk_HFPERCLKTIMER2] = clk_register_gate(NULL, "HFPERCLK.TIMER2",
57 "HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL);
58 clk[clk_HFPERCLKTIMER3] = clk_register_gate(NULL, "HFPERCLK.TIMER3",
59 "HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL);
60 clk[clk_HFPERCLKACMP0] = clk_register_gate(NULL, "HFPERCLK.ACMP0",
61 "HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL);
62 clk[clk_HFPERCLKACMP1] = clk_register_gate(NULL, "HFPERCLK.ACMP1",
63 "HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL);
64 clk[clk_HFPERCLKI2C0] = clk_register_gate(NULL, "HFPERCLK.I2C0",
65 "HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL);
66 clk[clk_HFPERCLKI2C1] = clk_register_gate(NULL, "HFPERCLK.I2C1",
67 "HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL);
68 clk[clk_HFPERCLKGPIO] = clk_register_gate(NULL, "HFPERCLK.GPIO",
69 "HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL);
70 clk[clk_HFPERCLKVCMP] = clk_register_gate(NULL, "HFPERCLK.VCMP",
71 "HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL);
72 clk[clk_HFPERCLKPRS] = clk_register_gate(NULL, "HFPERCLK.PRS",
73 "HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL);
74 clk[clk_HFPERCLKADC0] = clk_register_gate(NULL, "HFPERCLK.ADC0",
75 "HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL);
76 clk[clk_HFPERCLKDAC0] = clk_register_gate(NULL, "HFPERCLK.DAC0",
77 "HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL);
78
79 return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
80}
81CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init);
diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c
index 805b4c344006..b131041c8f48 100644
--- a/drivers/clk/clk-wm831x.c
+++ b/drivers/clk/clk-wm831x.c
@@ -391,14 +391,8 @@ static int wm831x_clk_probe(struct platform_device *pdev)
391 return 0; 391 return 0;
392} 392}
393 393
394static int wm831x_clk_remove(struct platform_device *pdev)
395{
396 return 0;
397}
398
399static struct platform_driver wm831x_clk_driver = { 394static struct platform_driver wm831x_clk_driver = {
400 .probe = wm831x_clk_probe, 395 .probe = wm831x_clk_probe,
401 .remove = wm831x_clk_remove,
402 .driver = { 396 .driver = {
403 .name = "wm831x-clk", 397 .name = "wm831x-clk",
404 .owner = THIS_MODULE, 398 .owner = THIS_MODULE,
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
new file mode 100644
index 000000000000..dd8a62d8f11f
--- /dev/null
+++ b/drivers/clk/clk-xgene.c
@@ -0,0 +1,521 @@
1/*
2 * clk-xgene.c - AppliedMicro X-Gene Clock Interface
3 *
4 * Copyright (c) 2013, Applied Micro Circuits Corporation
5 * Author: Loc Ho <lho@apm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
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, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 *
22 */
23#include <linux/module.h>
24#include <linux/spinlock.h>
25#include <linux/io.h>
26#include <linux/of.h>
27#include <linux/clkdev.h>
28#include <linux/clk-provider.h>
29#include <linux/of_address.h>
30#include <asm/setup.h>
31
32/* Register SCU_PCPPLL bit fields */
33#define N_DIV_RD(src) (((src) & 0x000001ff))
34
35/* Register SCU_SOCPLL bit fields */
36#define CLKR_RD(src) (((src) & 0x07000000)>>24)
37#define CLKOD_RD(src) (((src) & 0x00300000)>>20)
38#define REGSPEC_RESET_F1_MASK 0x00010000
39#define CLKF_RD(src) (((src) & 0x000001ff))
40
41#define XGENE_CLK_DRIVER_VER "0.1"
42
43static DEFINE_SPINLOCK(clk_lock);
44
45static inline u32 xgene_clk_read(void *csr)
46{
47 return readl_relaxed(csr);
48}
49
50static inline void xgene_clk_write(u32 data, void *csr)
51{
52 return writel_relaxed(data, csr);
53}
54
55/* PLL Clock */
56enum xgene_pll_type {
57 PLL_TYPE_PCP = 0,
58 PLL_TYPE_SOC = 1,
59};
60
61struct xgene_clk_pll {
62 struct clk_hw hw;
63 const char *name;
64 void __iomem *reg;
65 spinlock_t *lock;
66 u32 pll_offset;
67 enum xgene_pll_type type;
68};
69
70#define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw)
71
72static int xgene_clk_pll_is_enabled(struct clk_hw *hw)
73{
74 struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw);
75 u32 data;
76
77 data = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
78 pr_debug("%s pll %s\n", pllclk->name,
79 data & REGSPEC_RESET_F1_MASK ? "disabled" : "enabled");
80
81 return data & REGSPEC_RESET_F1_MASK ? 0 : 1;
82}
83
84static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,
85 unsigned long parent_rate)
86{
87 struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw);
88 unsigned long fref;
89 unsigned long fvco;
90 u32 pll;
91 u32 nref;
92 u32 nout;
93 u32 nfb;
94
95 pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
96
97 if (pllclk->type == PLL_TYPE_PCP) {
98 /*
99 * PLL VCO = Reference clock * NF
100 * PCP PLL = PLL_VCO / 2
101 */
102 nout = 2;
103 fvco = parent_rate * (N_DIV_RD(pll) + 4);
104 } else {
105 /*
106 * Fref = Reference Clock / NREF;
107 * Fvco = Fref * NFB;
108 * Fout = Fvco / NOUT;
109 */
110 nref = CLKR_RD(pll) + 1;
111 nout = CLKOD_RD(pll) + 1;
112 nfb = CLKF_RD(pll);
113 fref = parent_rate / nref;
114 fvco = fref * nfb;
115 }
116 pr_debug("%s pll recalc rate %ld parent %ld\n", pllclk->name,
117 fvco / nout, parent_rate);
118
119 return fvco / nout;
120}
121
122const struct clk_ops xgene_clk_pll_ops = {
123 .is_enabled = xgene_clk_pll_is_enabled,
124 .recalc_rate = xgene_clk_pll_recalc_rate,
125};
126
127static struct clk *xgene_register_clk_pll(struct device *dev,
128 const char *name, const char *parent_name,
129 unsigned long flags, void __iomem *reg, u32 pll_offset,
130 u32 type, spinlock_t *lock)
131{
132 struct xgene_clk_pll *apmclk;
133 struct clk *clk;
134 struct clk_init_data init;
135
136 /* allocate the APM clock structure */
137 apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
138 if (!apmclk) {
139 pr_err("%s: could not allocate APM clk\n", __func__);
140 return ERR_PTR(-ENOMEM);
141 }
142
143 init.name = name;
144 init.ops = &xgene_clk_pll_ops;
145 init.flags = flags;
146 init.parent_names = parent_name ? &parent_name : NULL;
147 init.num_parents = parent_name ? 1 : 0;
148
149 apmclk->name = name;
150 apmclk->reg = reg;
151 apmclk->lock = lock;
152 apmclk->pll_offset = pll_offset;
153 apmclk->type = type;
154 apmclk->hw.init = &init;
155
156 /* Register the clock */
157 clk = clk_register(dev, &apmclk->hw);
158 if (IS_ERR(clk)) {
159 pr_err("%s: could not register clk %s\n", __func__, name);
160 kfree(apmclk);
161 return NULL;
162 }
163 return clk;
164}
165
166static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type)
167{
168 const char *clk_name = np->full_name;
169 struct clk *clk;
170 void *reg;
171
172 reg = of_iomap(np, 0);
173 if (reg == NULL) {
174 pr_err("Unable to map CSR register for %s\n", np->full_name);
175 return;
176 }
177 of_property_read_string(np, "clock-output-names", &clk_name);
178 clk = xgene_register_clk_pll(NULL,
179 clk_name, of_clk_get_parent_name(np, 0),
180 CLK_IS_ROOT, reg, 0, pll_type, &clk_lock);
181 if (!IS_ERR(clk)) {
182 of_clk_add_provider(np, of_clk_src_simple_get, clk);
183 clk_register_clkdev(clk, clk_name, NULL);
184 pr_debug("Add %s clock PLL\n", clk_name);
185 }
186}
187
188static void xgene_socpllclk_init(struct device_node *np)
189{
190 xgene_pllclk_init(np, PLL_TYPE_SOC);
191}
192
193static void xgene_pcppllclk_init(struct device_node *np)
194{
195 xgene_pllclk_init(np, PLL_TYPE_PCP);
196}
197
198/* IP Clock */
199struct xgene_dev_parameters {
200 void __iomem *csr_reg; /* CSR for IP clock */
201 u32 reg_clk_offset; /* Offset to clock enable CSR */
202 u32 reg_clk_mask; /* Mask bit for clock enable */
203 u32 reg_csr_offset; /* Offset to CSR reset */
204 u32 reg_csr_mask; /* Mask bit for disable CSR reset */
205 void __iomem *divider_reg; /* CSR for divider */
206 u32 reg_divider_offset; /* Offset to divider register */
207 u32 reg_divider_shift; /* Bit shift to divider field */
208 u32 reg_divider_width; /* Width of the bit to divider field */
209};
210
211struct xgene_clk {
212 struct clk_hw hw;
213 const char *name;
214 spinlock_t *lock;
215 struct xgene_dev_parameters param;
216};
217
218#define to_xgene_clk(_hw) container_of(_hw, struct xgene_clk, hw)
219
220static int xgene_clk_enable(struct clk_hw *hw)
221{
222 struct xgene_clk *pclk = to_xgene_clk(hw);
223 unsigned long flags = 0;
224 u32 data;
225
226 if (pclk->lock)
227 spin_lock_irqsave(pclk->lock, flags);
228
229 if (pclk->param.csr_reg != NULL) {
230 pr_debug("%s clock enabled\n", pclk->name);
231 /* First enable the clock */
232 data = xgene_clk_read(pclk->param.csr_reg +
233 pclk->param.reg_clk_offset);
234 data |= pclk->param.reg_clk_mask;
235 xgene_clk_write(data, pclk->param.csr_reg +
236 pclk->param.reg_clk_offset);
237 pr_debug("%s clock PADDR base 0x%016LX clk offset 0x%08X mask 0x%08X value 0x%08X\n",
238 pclk->name, __pa(pclk->param.csr_reg),
239 pclk->param.reg_clk_offset, pclk->param.reg_clk_mask,
240 data);
241
242 /* Second enable the CSR */
243 data = xgene_clk_read(pclk->param.csr_reg +
244 pclk->param.reg_csr_offset);
245 data &= ~pclk->param.reg_csr_mask;
246 xgene_clk_write(data, pclk->param.csr_reg +
247 pclk->param.reg_csr_offset);
248 pr_debug("%s CSR RESET PADDR base 0x%016LX csr offset 0x%08X mask 0x%08X value 0x%08X\n",
249 pclk->name, __pa(pclk->param.csr_reg),
250 pclk->param.reg_csr_offset, pclk->param.reg_csr_mask,
251 data);
252 }
253
254 if (pclk->lock)
255 spin_unlock_irqrestore(pclk->lock, flags);
256
257 return 0;
258}
259
260static void xgene_clk_disable(struct clk_hw *hw)
261{
262 struct xgene_clk *pclk = to_xgene_clk(hw);
263 unsigned long flags = 0;
264 u32 data;
265
266 if (pclk->lock)
267 spin_lock_irqsave(pclk->lock, flags);
268
269 if (pclk->param.csr_reg != NULL) {
270 pr_debug("%s clock disabled\n", pclk->name);
271 /* First put the CSR in reset */
272 data = xgene_clk_read(pclk->param.csr_reg +
273 pclk->param.reg_csr_offset);
274 data |= pclk->param.reg_csr_mask;
275 xgene_clk_write(data, pclk->param.csr_reg +
276 pclk->param.reg_csr_offset);
277
278 /* Second disable the clock */
279 data = xgene_clk_read(pclk->param.csr_reg +
280 pclk->param.reg_clk_offset);
281 data &= ~pclk->param.reg_clk_mask;
282 xgene_clk_write(data, pclk->param.csr_reg +
283 pclk->param.reg_clk_offset);
284 }
285
286 if (pclk->lock)
287 spin_unlock_irqrestore(pclk->lock, flags);
288}
289
290static int xgene_clk_is_enabled(struct clk_hw *hw)
291{
292 struct xgene_clk *pclk = to_xgene_clk(hw);
293 u32 data = 0;
294
295 if (pclk->param.csr_reg != NULL) {
296 pr_debug("%s clock checking\n", pclk->name);
297 data = xgene_clk_read(pclk->param.csr_reg +
298 pclk->param.reg_clk_offset);
299 pr_debug("%s clock is %s\n", pclk->name,
300 data & pclk->param.reg_clk_mask ? "enabled" :
301 "disabled");
302 }
303
304 if (pclk->param.csr_reg == NULL)
305 return 1;
306 return data & pclk->param.reg_clk_mask ? 1 : 0;
307}
308
309static unsigned long xgene_clk_recalc_rate(struct clk_hw *hw,
310 unsigned long parent_rate)
311{
312 struct xgene_clk *pclk = to_xgene_clk(hw);
313 u32 data;
314
315 if (pclk->param.divider_reg) {
316 data = xgene_clk_read(pclk->param.divider_reg +
317 pclk->param.reg_divider_offset);
318 data >>= pclk->param.reg_divider_shift;
319 data &= (1 << pclk->param.reg_divider_width) - 1;
320
321 pr_debug("%s clock recalc rate %ld parent %ld\n",
322 pclk->name, parent_rate / data, parent_rate);
323 return parent_rate / data;
324 } else {
325 pr_debug("%s clock recalc rate %ld parent %ld\n",
326 pclk->name, parent_rate, parent_rate);
327 return parent_rate;
328 }
329}
330
331static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
332 unsigned long parent_rate)
333{
334 struct xgene_clk *pclk = to_xgene_clk(hw);
335 unsigned long flags = 0;
336 u32 data;
337 u32 divider;
338 u32 divider_save;
339
340 if (pclk->lock)
341 spin_lock_irqsave(pclk->lock, flags);
342
343 if (pclk->param.divider_reg) {
344 /* Let's compute the divider */
345 if (rate > parent_rate)
346 rate = parent_rate;
347 divider_save = divider = parent_rate / rate; /* Rounded down */
348 divider &= (1 << pclk->param.reg_divider_width) - 1;
349 divider <<= pclk->param.reg_divider_shift;
350
351 /* Set new divider */
352 data = xgene_clk_read(pclk->param.divider_reg +
353 pclk->param.reg_divider_offset);
354 data &= ~((1 << pclk->param.reg_divider_width) - 1);
355 data |= divider;
356 xgene_clk_write(data, pclk->param.divider_reg +
357 pclk->param.reg_divider_offset);
358 pr_debug("%s clock set rate %ld\n", pclk->name,
359 parent_rate / divider_save);
360 } else {
361 divider_save = 1;
362 }
363
364 if (pclk->lock)
365 spin_unlock_irqrestore(pclk->lock, flags);
366
367 return parent_rate / divider_save;
368}
369
370static long xgene_clk_round_rate(struct clk_hw *hw, unsigned long rate,
371 unsigned long *prate)
372{
373 struct xgene_clk *pclk = to_xgene_clk(hw);
374 unsigned long parent_rate = *prate;
375 u32 divider;
376
377 if (pclk->param.divider_reg) {
378 /* Let's compute the divider */
379 if (rate > parent_rate)
380 rate = parent_rate;
381 divider = parent_rate / rate; /* Rounded down */
382 } else {
383 divider = 1;
384 }
385
386 return parent_rate / divider;
387}
388
389const struct clk_ops xgene_clk_ops = {
390 .enable = xgene_clk_enable,
391 .disable = xgene_clk_disable,
392 .is_enabled = xgene_clk_is_enabled,
393 .recalc_rate = xgene_clk_recalc_rate,
394 .set_rate = xgene_clk_set_rate,
395 .round_rate = xgene_clk_round_rate,
396};
397
398static struct clk *xgene_register_clk(struct device *dev,
399 const char *name, const char *parent_name,
400 struct xgene_dev_parameters *parameters, spinlock_t *lock)
401{
402 struct xgene_clk *apmclk;
403 struct clk *clk;
404 struct clk_init_data init;
405 int rc;
406
407 /* allocate the APM clock structure */
408 apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL);
409 if (!apmclk) {
410 pr_err("%s: could not allocate APM clk\n", __func__);
411 return ERR_PTR(-ENOMEM);
412 }
413
414 init.name = name;
415 init.ops = &xgene_clk_ops;
416 init.flags = 0;
417 init.parent_names = parent_name ? &parent_name : NULL;
418 init.num_parents = parent_name ? 1 : 0;
419
420 apmclk->name = name;
421 apmclk->lock = lock;
422 apmclk->hw.init = &init;
423 apmclk->param = *parameters;
424
425 /* Register the clock */
426 clk = clk_register(dev, &apmclk->hw);
427 if (IS_ERR(clk)) {
428 pr_err("%s: could not register clk %s\n", __func__, name);
429 kfree(apmclk);
430 return clk;
431 }
432
433 /* Register the clock for lookup */
434 rc = clk_register_clkdev(clk, name, NULL);
435 if (rc != 0) {
436 pr_err("%s: could not register lookup clk %s\n",
437 __func__, name);
438 }
439 return clk;
440}
441
442static void __init xgene_devclk_init(struct device_node *np)
443{
444 const char *clk_name = np->full_name;
445 struct clk *clk;
446 struct resource res;
447 int rc;
448 struct xgene_dev_parameters parameters;
449 int i;
450
451 /* Check if the entry is disabled */
452 if (!of_device_is_available(np))
453 return;
454
455 /* Parse the DTS register for resource */
456 parameters.csr_reg = NULL;
457 parameters.divider_reg = NULL;
458 for (i = 0; i < 2; i++) {
459 void *map_res;
460 rc = of_address_to_resource(np, i, &res);
461 if (rc != 0) {
462 if (i == 0) {
463 pr_err("no DTS register for %s\n",
464 np->full_name);
465 return;
466 }
467 break;
468 }
469 map_res = of_iomap(np, i);
470 if (map_res == NULL) {
471 pr_err("Unable to map resource %d for %s\n",
472 i, np->full_name);
473 goto err;
474 }
475 if (strcmp(res.name, "div-reg") == 0)
476 parameters.divider_reg = map_res;
477 else /* if (strcmp(res->name, "csr-reg") == 0) */
478 parameters.csr_reg = map_res;
479 }
480 if (of_property_read_u32(np, "csr-offset", &parameters.reg_csr_offset))
481 parameters.reg_csr_offset = 0;
482 if (of_property_read_u32(np, "csr-mask", &parameters.reg_csr_mask))
483 parameters.reg_csr_mask = 0xF;
484 if (of_property_read_u32(np, "enable-offset",
485 &parameters.reg_clk_offset))
486 parameters.reg_clk_offset = 0x8;
487 if (of_property_read_u32(np, "enable-mask", &parameters.reg_clk_mask))
488 parameters.reg_clk_mask = 0xF;
489 if (of_property_read_u32(np, "divider-offset",
490 &parameters.reg_divider_offset))
491 parameters.reg_divider_offset = 0;
492 if (of_property_read_u32(np, "divider-width",
493 &parameters.reg_divider_width))
494 parameters.reg_divider_width = 0;
495 if (of_property_read_u32(np, "divider-shift",
496 &parameters.reg_divider_shift))
497 parameters.reg_divider_shift = 0;
498 of_property_read_string(np, "clock-output-names", &clk_name);
499
500 clk = xgene_register_clk(NULL, clk_name,
501 of_clk_get_parent_name(np, 0), &parameters, &clk_lock);
502 if (IS_ERR(clk))
503 goto err;
504 pr_debug("Add %s clock\n", clk_name);
505 rc = of_clk_add_provider(np, of_clk_src_simple_get, clk);
506 if (rc != 0)
507 pr_err("%s: could register provider clk %s\n", __func__,
508 np->full_name);
509
510 return;
511
512err:
513 if (parameters.csr_reg)
514 iounmap(parameters.csr_reg);
515 if (parameters.divider_reg)
516 iounmap(parameters.divider_reg);
517}
518
519CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init);
520CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init);
521CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a004769528e6..2cf2ea6b77a1 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1080,13 +1080,16 @@ unsigned long clk_get_rate(struct clk *clk)
1080} 1080}
1081EXPORT_SYMBOL_GPL(clk_get_rate); 1081EXPORT_SYMBOL_GPL(clk_get_rate);
1082 1082
1083static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent) 1083static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
1084{ 1084{
1085 u8 i; 1085 int i;
1086 1086
1087 if (!clk->parents) 1087 if (!clk->parents) {
1088 clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), 1088 clk->parents = kcalloc(clk->num_parents,
1089 GFP_KERNEL); 1089 sizeof(struct clk *), GFP_KERNEL);
1090 if (!clk->parents)
1091 return -ENOMEM;
1092 }
1090 1093
1091 /* 1094 /*
1092 * find index of new parent clock using cached parent ptrs, 1095 * find index of new parent clock using cached parent ptrs,
@@ -1094,16 +1097,19 @@ static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent)
1094 * them now to avoid future calls to __clk_lookup. 1097 * them now to avoid future calls to __clk_lookup.
1095 */ 1098 */
1096 for (i = 0; i < clk->num_parents; i++) { 1099 for (i = 0; i < clk->num_parents; i++) {
1097 if (clk->parents && clk->parents[i] == parent) 1100 if (clk->parents[i] == parent)
1098 break; 1101 return i;
1099 else if (!strcmp(clk->parent_names[i], parent->name)) { 1102
1100 if (clk->parents) 1103 if (clk->parents[i])
1101 clk->parents[i] = __clk_lookup(parent->name); 1104 continue;
1102 break; 1105
1106 if (!strcmp(clk->parent_names[i], parent->name)) {
1107 clk->parents[i] = __clk_lookup(parent->name);
1108 return i;
1103 } 1109 }
1104 } 1110 }
1105 1111
1106 return i; 1112 return -EINVAL;
1107} 1113}
1108 1114
1109static void clk_reparent(struct clk *clk, struct clk *new_parent) 1115static void clk_reparent(struct clk *clk, struct clk *new_parent)
@@ -1265,7 +1271,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
1265 struct clk *old_parent, *parent; 1271 struct clk *old_parent, *parent;
1266 unsigned long best_parent_rate = 0; 1272 unsigned long best_parent_rate = 0;
1267 unsigned long new_rate; 1273 unsigned long new_rate;
1268 u8 p_index = 0; 1274 int p_index = 0;
1269 1275
1270 /* sanity */ 1276 /* sanity */
1271 if (IS_ERR_OR_NULL(clk)) 1277 if (IS_ERR_OR_NULL(clk))
@@ -1306,7 +1312,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
1306 /* try finding the new parent index */ 1312 /* try finding the new parent index */
1307 if (parent) { 1313 if (parent) {
1308 p_index = clk_fetch_parent_index(clk, parent); 1314 p_index = clk_fetch_parent_index(clk, parent);
1309 if (p_index == clk->num_parents) { 1315 if (p_index < 0) {
1310 pr_debug("%s: clk %s can not be parent of clk %s\n", 1316 pr_debug("%s: clk %s can not be parent of clk %s\n",
1311 __func__, parent->name, clk->name); 1317 __func__, parent->name, clk->name);
1312 return NULL; 1318 return NULL;
@@ -1532,7 +1538,7 @@ static struct clk *__clk_init_parent(struct clk *clk)
1532 1538
1533 if (!clk->parents) 1539 if (!clk->parents)
1534 clk->parents = 1540 clk->parents =
1535 kzalloc((sizeof(struct clk*) * clk->num_parents), 1541 kcalloc(clk->num_parents, sizeof(struct clk *),
1536 GFP_KERNEL); 1542 GFP_KERNEL);
1537 1543
1538 ret = clk_get_parent_by_index(clk, index); 1544 ret = clk_get_parent_by_index(clk, index);
@@ -1568,7 +1574,7 @@ void __clk_reparent(struct clk *clk, struct clk *new_parent)
1568int clk_set_parent(struct clk *clk, struct clk *parent) 1574int clk_set_parent(struct clk *clk, struct clk *parent)
1569{ 1575{
1570 int ret = 0; 1576 int ret = 0;
1571 u8 p_index = 0; 1577 int p_index = 0;
1572 unsigned long p_rate = 0; 1578 unsigned long p_rate = 0;
1573 1579
1574 if (!clk) 1580 if (!clk)
@@ -1597,10 +1603,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
1597 if (parent) { 1603 if (parent) {
1598 p_index = clk_fetch_parent_index(clk, parent); 1604 p_index = clk_fetch_parent_index(clk, parent);
1599 p_rate = parent->rate; 1605 p_rate = parent->rate;
1600 if (p_index == clk->num_parents) { 1606 if (p_index < 0) {
1601 pr_debug("%s: clk %s can not be parent of clk %s\n", 1607 pr_debug("%s: clk %s can not be parent of clk %s\n",
1602 __func__, parent->name, clk->name); 1608 __func__, parent->name, clk->name);
1603 ret = -EINVAL; 1609 ret = p_index;
1604 goto out; 1610 goto out;
1605 } 1611 }
1606 } 1612 }
@@ -1689,8 +1695,8 @@ int __clk_init(struct device *dev, struct clk *clk)
1689 * for clock drivers to statically initialize clk->parents. 1695 * for clock drivers to statically initialize clk->parents.
1690 */ 1696 */
1691 if (clk->num_parents > 1 && !clk->parents) { 1697 if (clk->num_parents > 1 && !clk->parents) {
1692 clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), 1698 clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
1693 GFP_KERNEL); 1699 GFP_KERNEL);
1694 /* 1700 /*
1695 * __clk_lookup returns NULL for parents that have not been 1701 * __clk_lookup returns NULL for parents that have not been
1696 * clk_init'd; thus any access to clk->parents[] must check 1702 * clk_init'd; thus any access to clk->parents[] must check
@@ -1830,8 +1836,8 @@ static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk)
1830 hw->clk = clk; 1836 hw->clk = clk;
1831 1837
1832 /* allocate local copy in case parent_names is __initdata */ 1838 /* allocate local copy in case parent_names is __initdata */
1833 clk->parent_names = kzalloc((sizeof(char*) * clk->num_parents), 1839 clk->parent_names = kcalloc(clk->num_parents, sizeof(char *),
1834 GFP_KERNEL); 1840 GFP_KERNEL);
1835 1841
1836 if (!clk->parent_names) { 1842 if (!clk->parent_names) {
1837 pr_err("%s: could not allocate clk->parent_names\n", __func__); 1843 pr_err("%s: could not allocate clk->parent_names\n", __func__);
@@ -2196,6 +2202,12 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
2196 return clk; 2202 return clk;
2197} 2203}
2198 2204
2205int of_clk_get_parent_count(struct device_node *np)
2206{
2207 return of_count_phandle_with_args(np, "clocks", "#clock-cells");
2208}
2209EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
2210
2199const char *of_clk_get_parent_name(struct device_node *np, int index) 2211const char *of_clk_get_parent_name(struct device_node *np, int index)
2200{ 2212{
2201 struct of_phandle_args clkspec; 2213 struct of_phandle_args clkspec;
diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
new file mode 100644
index 000000000000..0477cf63f132
--- /dev/null
+++ b/drivers/clk/keystone/Makefile
@@ -0,0 +1 @@
obj-y += pll.o gate.o
diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c
new file mode 100644
index 000000000000..1f333bcfc22e
--- /dev/null
+++ b/drivers/clk/keystone/gate.c
@@ -0,0 +1,264 @@
1/*
2 * Clock driver for Keystone 2 based devices
3 *
4 * Copyright (C) 2013 Texas Instruments.
5 * Murali Karicheri <m-karicheri2@ti.com>
6 * Santosh Shilimkar <santosh.shilimkar@ti.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include <linux/of_address.h>
19#include <linux/of.h>
20#include <linux/module.h>
21
22/* PSC register offsets */
23#define PTCMD 0x120
24#define PTSTAT 0x128
25#define PDSTAT 0x200
26#define PDCTL 0x300
27#define MDSTAT 0x800
28#define MDCTL 0xa00
29
30/* PSC module states */
31#define PSC_STATE_SWRSTDISABLE 0
32#define PSC_STATE_SYNCRST 1
33#define PSC_STATE_DISABLE 2
34#define PSC_STATE_ENABLE 3
35
36#define MDSTAT_STATE_MASK 0x3f
37#define MDSTAT_MCKOUT BIT(12)
38#define PDSTAT_STATE_MASK 0x1f
39#define MDCTL_FORCE BIT(31)
40#define MDCTL_LRESET BIT(8)
41#define PDCTL_NEXT BIT(0)
42
43/* Maximum timeout to bail out state transition for module */
44#define STATE_TRANS_MAX_COUNT 0xffff
45
46static void __iomem *domain_transition_base;
47
48/**
49 * struct clk_psc_data - PSC data
50 * @control_base: Base address for a PSC control
51 * @domain_base: Base address for a PSC domain
52 * @domain_id: PSC domain id number
53 */
54struct clk_psc_data {
55 void __iomem *control_base;
56 void __iomem *domain_base;
57 u32 domain_id;
58};
59
60/**
61 * struct clk_psc - PSC clock structure
62 * @hw: clk_hw for the psc
63 * @psc_data: PSC driver specific data
64 * @lock: Spinlock used by the driver
65 */
66struct clk_psc {
67 struct clk_hw hw;
68 struct clk_psc_data *psc_data;
69 spinlock_t *lock;
70};
71
72static DEFINE_SPINLOCK(psc_lock);
73
74#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
75
76static void psc_config(void __iomem *control_base, void __iomem *domain_base,
77 u32 next_state, u32 domain_id)
78{
79 u32 ptcmd, pdstat, pdctl, mdstat, mdctl, ptstat;
80 u32 count = STATE_TRANS_MAX_COUNT;
81
82 mdctl = readl(control_base + MDCTL);
83 mdctl &= ~MDSTAT_STATE_MASK;
84 mdctl |= next_state;
85 /* For disable, we always put the module in local reset */
86 if (next_state == PSC_STATE_DISABLE)
87 mdctl &= ~MDCTL_LRESET;
88 writel(mdctl, control_base + MDCTL);
89
90 pdstat = readl(domain_base + PDSTAT);
91 if (!(pdstat & PDSTAT_STATE_MASK)) {
92 pdctl = readl(domain_base + PDCTL);
93 pdctl |= PDCTL_NEXT;
94 writel(pdctl, domain_base + PDCTL);
95 }
96
97 ptcmd = 1 << domain_id;
98 writel(ptcmd, domain_transition_base + PTCMD);
99 do {
100 ptstat = readl(domain_transition_base + PTSTAT);
101 } while (((ptstat >> domain_id) & 1) && count--);
102
103 count = STATE_TRANS_MAX_COUNT;
104 do {
105 mdstat = readl(control_base + MDSTAT);
106 } while (!((mdstat & MDSTAT_STATE_MASK) == next_state) && count--);
107}
108
109static int keystone_clk_is_enabled(struct clk_hw *hw)
110{
111 struct clk_psc *psc = to_clk_psc(hw);
112 struct clk_psc_data *data = psc->psc_data;
113 u32 mdstat = readl(data->control_base + MDSTAT);
114
115 return (mdstat & MDSTAT_MCKOUT) ? 1 : 0;
116}
117
118static int keystone_clk_enable(struct clk_hw *hw)
119{
120 struct clk_psc *psc = to_clk_psc(hw);
121 struct clk_psc_data *data = psc->psc_data;
122 unsigned long flags = 0;
123
124 if (psc->lock)
125 spin_lock_irqsave(psc->lock, flags);
126
127 psc_config(data->control_base, data->domain_base,
128 PSC_STATE_ENABLE, data->domain_id);
129
130 if (psc->lock)
131 spin_unlock_irqrestore(psc->lock, flags);
132
133 return 0;
134}
135
136static void keystone_clk_disable(struct clk_hw *hw)
137{
138 struct clk_psc *psc = to_clk_psc(hw);
139 struct clk_psc_data *data = psc->psc_data;
140 unsigned long flags = 0;
141
142 if (psc->lock)
143 spin_lock_irqsave(psc->lock, flags);
144
145 psc_config(data->control_base, data->domain_base,
146 PSC_STATE_DISABLE, data->domain_id);
147
148 if (psc->lock)
149 spin_unlock_irqrestore(psc->lock, flags);
150}
151
152static const struct clk_ops clk_psc_ops = {
153 .enable = keystone_clk_enable,
154 .disable = keystone_clk_disable,
155 .is_enabled = keystone_clk_is_enabled,
156};
157
158/**
159 * clk_register_psc - register psc clock
160 * @dev: device that is registering this clock
161 * @name: name of this clock
162 * @parent_name: name of clock's parent
163 * @psc_data: platform data to configure this clock
164 * @lock: spinlock used by this clock
165 */
166static struct clk *clk_register_psc(struct device *dev,
167 const char *name,
168 const char *parent_name,
169 struct clk_psc_data *psc_data,
170 spinlock_t *lock)
171{
172 struct clk_init_data init;
173 struct clk_psc *psc;
174 struct clk *clk;
175
176 psc = kzalloc(sizeof(*psc), GFP_KERNEL);
177 if (!psc)
178 return ERR_PTR(-ENOMEM);
179
180 init.name = name;
181 init.ops = &clk_psc_ops;
182 init.parent_names = (parent_name ? &parent_name : NULL);
183 init.num_parents = (parent_name ? 1 : 0);
184
185 psc->psc_data = psc_data;
186 psc->lock = lock;
187 psc->hw.init = &init;
188
189 clk = clk_register(NULL, &psc->hw);
190 if (IS_ERR(clk))
191 kfree(psc);
192
193 return clk;
194}
195
196/**
197 * of_psc_clk_init - initialize psc clock through DT
198 * @node: device tree node for this clock
199 * @lock: spinlock used by this clock
200 */
201static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock)
202{
203 const char *clk_name = node->name;
204 const char *parent_name;
205 struct clk_psc_data *data;
206 struct clk *clk;
207 int i;
208
209 data = kzalloc(sizeof(*data), GFP_KERNEL);
210 if (!data) {
211 pr_err("%s: Out of memory\n", __func__);
212 return;
213 }
214
215 i = of_property_match_string(node, "reg-names", "control");
216 data->control_base = of_iomap(node, i);
217 if (!data->control_base) {
218 pr_err("%s: control ioremap failed\n", __func__);
219 goto out;
220 }
221
222 i = of_property_match_string(node, "reg-names", "domain");
223 data->domain_base = of_iomap(node, i);
224 if (!data->domain_base) {
225 pr_err("%s: domain ioremap failed\n", __func__);
226 iounmap(data->control_base);
227 goto out;
228 }
229
230 of_property_read_u32(node, "domain-id", &data->domain_id);
231
232 /* Domain transition registers at fixed address space of domain_id 0 */
233 if (!domain_transition_base && !data->domain_id)
234 domain_transition_base = data->domain_base;
235
236 of_property_read_string(node, "clock-output-names", &clk_name);
237 parent_name = of_clk_get_parent_name(node, 0);
238 if (!parent_name) {
239 pr_err("%s: Parent clock not found\n", __func__);
240 goto out;
241 }
242
243 clk = clk_register_psc(NULL, clk_name, parent_name, data, lock);
244 if (clk) {
245 of_clk_add_provider(node, of_clk_src_simple_get, clk);
246 return;
247 }
248
249 pr_err("%s: error registering clk %s\n", __func__, node->name);
250out:
251 kfree(data);
252 return;
253}
254
255/**
256 * of_keystone_psc_clk_init - initialize psc clock through DT
257 * @node: device tree node for this clock
258 */
259static void __init of_keystone_psc_clk_init(struct device_node *node)
260{
261 of_psc_clk_init(node, &psc_lock);
262}
263CLK_OF_DECLARE(keystone_gate_clk, "ti,keystone,psc-clock",
264 of_keystone_psc_clk_init);
diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c
new file mode 100644
index 000000000000..47a1bd9f1726
--- /dev/null
+++ b/drivers/clk/keystone/pll.c
@@ -0,0 +1,305 @@
1/*
2 * PLL clock driver for Keystone devices
3 *
4 * Copyright (C) 2013 Texas Instruments Inc.
5 * Murali Karicheri <m-karicheri2@ti.com>
6 * Santosh Shilimkar <santosh.shilimkar@ti.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13#include <linux/clk.h>
14#include <linux/clk-provider.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include <linux/of_address.h>
19#include <linux/of.h>
20#include <linux/module.h>
21
22#define PLLM_LOW_MASK 0x3f
23#define PLLM_HIGH_MASK 0x7ffc0
24#define MAIN_PLLM_HIGH_MASK 0x7f000
25#define PLLM_HIGH_SHIFT 6
26#define PLLD_MASK 0x3f
27
28/**
29 * struct clk_pll_data - pll data structure
30 * @has_pllctrl: If set to non zero, lower 6 bits of multiplier is in pllm
31 * register of pll controller, else it is in the pll_ctrl0((bit 11-6)
32 * @phy_pllm: Physical address of PLLM in pll controller. Used when
33 * has_pllctrl is non zero.
34 * @phy_pll_ctl0: Physical address of PLL ctrl0. This could be that of
35 * Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL
36 * or PA PLL available on keystone2. These PLLs are controlled by
37 * this register. Main PLL is controlled by a PLL controller.
38 * @pllm: PLL register map address
39 * @pll_ctl0: PLL controller map address
40 * @pllm_lower_mask: multiplier lower mask
41 * @pllm_upper_mask: multiplier upper mask
42 * @pllm_upper_shift: multiplier upper shift
43 * @plld_mask: divider mask
44 * @postdiv: Post divider
45 */
46struct clk_pll_data {
47 bool has_pllctrl;
48 u32 phy_pllm;
49 u32 phy_pll_ctl0;
50 void __iomem *pllm;
51 void __iomem *pll_ctl0;
52 u32 pllm_lower_mask;
53 u32 pllm_upper_mask;
54 u32 pllm_upper_shift;
55 u32 plld_mask;
56 u32 postdiv;
57};
58
59/**
60 * struct clk_pll - Main pll clock
61 * @hw: clk_hw for the pll
62 * @pll_data: PLL driver specific data
63 */
64struct clk_pll {
65 struct clk_hw hw;
66 struct clk_pll_data *pll_data;
67};
68
69#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
70
71static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
72 unsigned long parent_rate)
73{
74 struct clk_pll *pll = to_clk_pll(hw);
75 struct clk_pll_data *pll_data = pll->pll_data;
76 unsigned long rate = parent_rate;
77 u32 mult = 0, prediv, postdiv, val;
78
79 /*
80 * get bits 0-5 of multiplier from pllctrl PLLM register
81 * if has_pllctrl is non zero
82 */
83 if (pll_data->has_pllctrl) {
84 val = readl(pll_data->pllm);
85 mult = (val & pll_data->pllm_lower_mask);
86 }
87
88 /* bit6-12 of PLLM is in Main PLL control register */
89 val = readl(pll_data->pll_ctl0);
90 mult |= ((val & pll_data->pllm_upper_mask)
91 >> pll_data->pllm_upper_shift);
92 prediv = (val & pll_data->plld_mask);
93 postdiv = pll_data->postdiv;
94
95 rate /= (prediv + 1);
96 rate = (rate * (mult + 1));
97 rate /= postdiv;
98
99 return rate;
100}
101
102static const struct clk_ops clk_pll_ops = {
103 .recalc_rate = clk_pllclk_recalc,
104};
105
106static struct clk *clk_register_pll(struct device *dev,
107 const char *name,
108 const char *parent_name,
109 struct clk_pll_data *pll_data)
110{
111 struct clk_init_data init;
112 struct clk_pll *pll;
113 struct clk *clk;
114
115 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
116 if (!pll)
117 return ERR_PTR(-ENOMEM);
118
119 init.name = name;
120 init.ops = &clk_pll_ops;
121 init.flags = 0;
122 init.parent_names = (parent_name ? &parent_name : NULL);
123 init.num_parents = (parent_name ? 1 : 0);
124
125 pll->pll_data = pll_data;
126 pll->hw.init = &init;
127
128 clk = clk_register(NULL, &pll->hw);
129 if (IS_ERR(clk))
130 goto out;
131
132 return clk;
133out:
134 kfree(pll);
135 return NULL;
136}
137
138/**
139 * _of_clk_init - PLL initialisation via DT
140 * @node: device tree node for this clock
141 * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of
142 * pll controller, else it is in the control regsiter0(bit 11-6)
143 */
144static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl)
145{
146 struct clk_pll_data *pll_data;
147 const char *parent_name;
148 struct clk *clk;
149 int i;
150
151 pll_data = kzalloc(sizeof(*pll_data), GFP_KERNEL);
152 if (!pll_data) {
153 pr_err("%s: Out of memory\n", __func__);
154 return;
155 }
156
157 parent_name = of_clk_get_parent_name(node, 0);
158 if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv))
159 goto out;
160
161 i = of_property_match_string(node, "reg-names", "control");
162 pll_data->pll_ctl0 = of_iomap(node, i);
163 if (!pll_data->pll_ctl0) {
164 pr_err("%s: ioremap failed\n", __func__);
165 goto out;
166 }
167
168 pll_data->pllm_lower_mask = PLLM_LOW_MASK;
169 pll_data->pllm_upper_shift = PLLM_HIGH_SHIFT;
170 pll_data->plld_mask = PLLD_MASK;
171 pll_data->has_pllctrl = pllctrl;
172 if (!pll_data->has_pllctrl) {
173 pll_data->pllm_upper_mask = PLLM_HIGH_MASK;
174 } else {
175 pll_data->pllm_upper_mask = MAIN_PLLM_HIGH_MASK;
176 i = of_property_match_string(node, "reg-names", "multiplier");
177 pll_data->pllm = of_iomap(node, i);
178 if (!pll_data->pllm) {
179 iounmap(pll_data->pll_ctl0);
180 goto out;
181 }
182 }
183
184 clk = clk_register_pll(NULL, node->name, parent_name, pll_data);
185 if (clk) {
186 of_clk_add_provider(node, of_clk_src_simple_get, clk);
187 return;
188 }
189
190out:
191 pr_err("%s: error initializing pll %s\n", __func__, node->name);
192 kfree(pll_data);
193}
194
195/**
196 * of_keystone_pll_clk_init - PLL initialisation DT wrapper
197 * @node: device tree node for this clock
198 */
199static void __init of_keystone_pll_clk_init(struct device_node *node)
200{
201 _of_pll_clk_init(node, false);
202}
203CLK_OF_DECLARE(keystone_pll_clock, "ti,keystone,pll-clock",
204 of_keystone_pll_clk_init);
205
206/**
207 * of_keystone_pll_main_clk_init - Main PLL initialisation DT wrapper
208 * @node: device tree node for this clock
209 */
210static void __init of_keystone_main_pll_clk_init(struct device_node *node)
211{
212 _of_pll_clk_init(node, true);
213}
214CLK_OF_DECLARE(keystone_main_pll_clock, "ti,keystone,main-pll-clock",
215 of_keystone_main_pll_clk_init);
216
217/**
218 * of_pll_div_clk_init - PLL divider setup function
219 * @node: device tree node for this clock
220 */
221static void __init of_pll_div_clk_init(struct device_node *node)
222{
223 const char *parent_name;
224 void __iomem *reg;
225 u32 shift, mask;
226 struct clk *clk;
227 const char *clk_name = node->name;
228
229 of_property_read_string(node, "clock-output-names", &clk_name);
230 reg = of_iomap(node, 0);
231 if (!reg) {
232 pr_err("%s: ioremap failed\n", __func__);
233 return;
234 }
235
236 parent_name = of_clk_get_parent_name(node, 0);
237 if (!parent_name) {
238 pr_err("%s: missing parent clock\n", __func__);
239 return;
240 }
241
242 if (of_property_read_u32(node, "bit-shift", &shift)) {
243 pr_err("%s: missing 'shift' property\n", __func__);
244 return;
245 }
246
247 if (of_property_read_u32(node, "bit-mask", &mask)) {
248 pr_err("%s: missing 'bit-mask' property\n", __func__);
249 return;
250 }
251
252 clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift,
253 mask, 0, NULL);
254 if (clk)
255 of_clk_add_provider(node, of_clk_src_simple_get, clk);
256 else
257 pr_err("%s: error registering divider %s\n", __func__, clk_name);
258}
259CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init);
260
261/**
262 * of_pll_mux_clk_init - PLL mux setup function
263 * @node: device tree node for this clock
264 */
265static void __init of_pll_mux_clk_init(struct device_node *node)
266{
267 void __iomem *reg;
268 u32 shift, mask;
269 struct clk *clk;
270 const char *parents[2];
271 const char *clk_name = node->name;
272
273 of_property_read_string(node, "clock-output-names", &clk_name);
274 reg = of_iomap(node, 0);
275 if (!reg) {
276 pr_err("%s: ioremap failed\n", __func__);
277 return;
278 }
279
280 parents[0] = of_clk_get_parent_name(node, 0);
281 parents[1] = of_clk_get_parent_name(node, 1);
282 if (!parents[0] || !parents[1]) {
283 pr_err("%s: missing parent clocks\n", __func__);
284 return;
285 }
286
287 if (of_property_read_u32(node, "bit-shift", &shift)) {
288 pr_err("%s: missing 'shift' property\n", __func__);
289 return;
290 }
291
292 if (of_property_read_u32(node, "bit-mask", &mask)) {
293 pr_err("%s: missing 'bit-mask' property\n", __func__);
294 return;
295 }
296
297 clk = clk_register_mux(NULL, clk_name, (const char **)&parents,
298 ARRAY_SIZE(parents) , 0, reg, shift, mask,
299 0, NULL);
300 if (clk)
301 of_clk_add_provider(node, of_clk_src_simple_get, clk);
302 else
303 pr_err("%s: error registering mux %s\n", __func__, clk_name);
304}
305CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init);
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index cc40fe64f2dc..10772aa72e4e 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -117,13 +117,19 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
117 goto err; 117 goto err;
118 fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL); 118 fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL);
119 if (!fclk_gate_lock) 119 if (!fclk_gate_lock)
120 goto err; 120 goto err_fclk_gate_lock;
121 spin_lock_init(fclk_lock); 121 spin_lock_init(fclk_lock);
122 spin_lock_init(fclk_gate_lock); 122 spin_lock_init(fclk_gate_lock);
123 123
124 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name); 124 mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name);
125 if (!mux_name)
126 goto err_mux_name;
125 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); 127 div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name);
128 if (!div0_name)
129 goto err_div0_name;
126 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); 130 div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name);
131 if (!div1_name)
132 goto err_div1_name;
127 133
128 clk = clk_register_mux(NULL, mux_name, parents, 4, 134 clk = clk_register_mux(NULL, mux_name, parents, 4,
129 CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0, 135 CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0,
@@ -147,6 +153,14 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
147 153
148 return; 154 return;
149 155
156err_div1_name:
157 kfree(div0_name);
158err_div0_name:
159 kfree(mux_name);
160err_mux_name:
161 kfree(fclk_gate_lock);
162err_fclk_gate_lock:
163 kfree(fclk_lock);
150err: 164err:
151 clks[fclk] = ERR_PTR(-ENOMEM); 165 clks[fclk] = ERR_PTR(-ENOMEM);
152} 166}