aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/Kconfig6
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/at91/clk-master.c2
-rw-r--r--drivers/clk/clk-axi-clkgen.c312
-rw-r--r--drivers/clk/clk-divider.c10
-rw-r--r--drivers/clk/clk-moxart.c97
-rw-r--r--drivers/clk/clk-nomadik.c3
-rw-r--r--drivers/clk/clk-s2mps11.c25
-rw-r--r--drivers/clk/clk.c55
-rw-r--r--drivers/clk/clkdev.c2
-rw-r--r--drivers/clk/hisilicon/clk-hi3620.c274
-rw-r--r--drivers/clk/keystone/gate.c1
-rw-r--r--drivers/clk/mvebu/armada-370.c21
-rw-r--r--drivers/clk/mvebu/armada-xp.c20
-rw-r--r--drivers/clk/mvebu/dove.c19
-rw-r--r--drivers/clk/mvebu/kirkwood.c34
-rw-r--r--drivers/clk/shmobile/clk-div6.c2
-rw-r--r--drivers/clk/shmobile/clk-rcar-gen2.c12
-rw-r--r--drivers/clk/socfpga/Makefile3
-rw-r--r--drivers/clk/socfpga/clk-gate.c263
-rw-r--r--drivers/clk/socfpga/clk-periph.c94
-rw-r--r--drivers/clk/socfpga/clk-pll.c131
-rw-r--r--drivers/clk/socfpga/clk.c326
-rw-r--r--drivers/clk/socfpga/clk.h57
-rw-r--r--drivers/clk/tegra/clk-divider.c2
-rw-r--r--drivers/clk/tegra/clk-id.h4
-rw-r--r--drivers/clk/tegra/clk-periph.c2
-rw-r--r--drivers/clk/tegra/clk-tegra-periph.c10
-rw-r--r--drivers/clk/tegra/clk-tegra-super-gen4.c2
-rw-r--r--drivers/clk/tegra/clk-tegra114.c8
-rw-r--r--drivers/clk/tegra/clk-tegra124.c48
-rw-r--r--drivers/clk/tegra/clk-tegra20.c2
-rw-r--r--drivers/clk/ti/clk-33xx.c1
-rw-r--r--drivers/clk/ti/divider.c8
-rw-r--r--drivers/clk/ux500/u8500_of_clk.c3
-rw-r--r--drivers/clk/zynq/clkc.c4
-rw-r--r--drivers/clk/zynq/pll.c18
37 files changed, 1390 insertions, 492 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7641965d208d..da1b416aa579 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -65,10 +65,12 @@ config COMMON_CLK_SI570
65 clock generators. 65 clock generators.
66 66
67config COMMON_CLK_S2MPS11 67config COMMON_CLK_S2MPS11
68 tristate "Clock driver for S2MPS11 MFD" 68 tristate "Clock driver for S2MPS11/S5M8767 MFD"
69 depends on MFD_SEC_CORE 69 depends on MFD_SEC_CORE
70 ---help--- 70 ---help---
71 This driver supports S2MPS11 crystal oscillator clock. 71 This driver supports S2MPS11/S5M8767 crystal oscillator clock. These
72 multi-function devices have 3 fixed-rate oscillators, clocked at
73 32KHz each.
72 74
73config CLK_TWL6040 75config CLK_TWL6040
74 tristate "External McPDM functional clock from twl6040" 76 tristate "External McPDM functional clock from twl6040"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index a367a9831717..48a7ef3d05f6 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
17obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 17obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
18obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o 18obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
19obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 19obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
20obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
20obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 21obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
21obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 22obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
22obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o 23obj-$(CONFIG_CLK_PPC_CORENET) += clk-ppc-corenet.o
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c
index bd313f7816a8..c1af80bcdf20 100644
--- a/drivers/clk/at91/clk-master.c
+++ b/drivers/clk/at91/clk-master.c
@@ -242,7 +242,7 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc,
242 242
243 irq = irq_of_parse_and_map(np, 0); 243 irq = irq_of_parse_and_map(np, 0);
244 if (!irq) 244 if (!irq)
245 return; 245 goto out_free_characteristics;
246 246
247 clk = at91_clk_register_master(pmc, irq, name, num_parents, 247 clk = at91_clk_register_master(pmc, irq, name, num_parents,
248 parent_names, layout, 248 parent_names, layout,
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
index 8137327847c3..1127ee46b802 100644
--- a/drivers/clk/clk-axi-clkgen.c
+++ b/drivers/clk/clk-axi-clkgen.c
@@ -17,23 +17,75 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/err.h> 18#include <linux/err.h>
19 19
20#define AXI_CLKGEN_REG_UPDATE_ENABLE 0x04 20#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04
21#define AXI_CLKGEN_REG_CLK_OUT1 0x08 21#define AXI_CLKGEN_V1_REG_CLK_OUT1 0x08
22#define AXI_CLKGEN_REG_CLK_OUT2 0x0c 22#define AXI_CLKGEN_V1_REG_CLK_OUT2 0x0c
23#define AXI_CLKGEN_REG_CLK_DIV 0x10 23#define AXI_CLKGEN_V1_REG_CLK_DIV 0x10
24#define AXI_CLKGEN_REG_CLK_FB1 0x14 24#define AXI_CLKGEN_V1_REG_CLK_FB1 0x14
25#define AXI_CLKGEN_REG_CLK_FB2 0x18 25#define AXI_CLKGEN_V1_REG_CLK_FB2 0x18
26#define AXI_CLKGEN_REG_LOCK1 0x1c 26#define AXI_CLKGEN_V1_REG_LOCK1 0x1c
27#define AXI_CLKGEN_REG_LOCK2 0x20 27#define AXI_CLKGEN_V1_REG_LOCK2 0x20
28#define AXI_CLKGEN_REG_LOCK3 0x24 28#define AXI_CLKGEN_V1_REG_LOCK3 0x24
29#define AXI_CLKGEN_REG_FILTER1 0x28 29#define AXI_CLKGEN_V1_REG_FILTER1 0x28
30#define AXI_CLKGEN_REG_FILTER2 0x2c 30#define AXI_CLKGEN_V1_REG_FILTER2 0x2c
31
32#define AXI_CLKGEN_V2_REG_RESET 0x40
33#define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70
34#define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74
35
36#define AXI_CLKGEN_V2_RESET_MMCM_ENABLE BIT(1)
37#define AXI_CLKGEN_V2_RESET_ENABLE BIT(0)
38
39#define AXI_CLKGEN_V2_DRP_CNTRL_SEL BIT(29)
40#define AXI_CLKGEN_V2_DRP_CNTRL_READ BIT(28)
41
42#define AXI_CLKGEN_V2_DRP_STATUS_BUSY BIT(16)
43
44#define MMCM_REG_CLKOUT0_1 0x08
45#define MMCM_REG_CLKOUT0_2 0x09
46#define MMCM_REG_CLK_FB1 0x14
47#define MMCM_REG_CLK_FB2 0x15
48#define MMCM_REG_CLK_DIV 0x16
49#define MMCM_REG_LOCK1 0x18
50#define MMCM_REG_LOCK2 0x19
51#define MMCM_REG_LOCK3 0x1a
52#define MMCM_REG_FILTER1 0x4e
53#define MMCM_REG_FILTER2 0x4f
54
55struct axi_clkgen;
56
57struct axi_clkgen_mmcm_ops {
58 void (*enable)(struct axi_clkgen *axi_clkgen, bool enable);
59 int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg,
60 unsigned int val, unsigned int mask);
61 int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg,
62 unsigned int *val);
63};
31 64
32struct axi_clkgen { 65struct axi_clkgen {
33 void __iomem *base; 66 void __iomem *base;
67 const struct axi_clkgen_mmcm_ops *mmcm_ops;
34 struct clk_hw clk_hw; 68 struct clk_hw clk_hw;
35}; 69};
36 70
71static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen,
72 bool enable)
73{
74 axi_clkgen->mmcm_ops->enable(axi_clkgen, enable);
75}
76
77static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen,
78 unsigned int reg, unsigned int val, unsigned int mask)
79{
80 return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask);
81}
82
83static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen,
84 unsigned int reg, unsigned int *val)
85{
86 return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val);
87}
88
37static uint32_t axi_clkgen_lookup_filter(unsigned int m) 89static uint32_t axi_clkgen_lookup_filter(unsigned int m)
38{ 90{
39 switch (m) { 91 switch (m) {
@@ -156,6 +208,148 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
156 *val = readl(axi_clkgen->base + reg); 208 *val = readl(axi_clkgen->base + reg);
157} 209}
158 210
211static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg)
212{
213 switch (reg) {
214 case MMCM_REG_CLKOUT0_1:
215 return AXI_CLKGEN_V1_REG_CLK_OUT1;
216 case MMCM_REG_CLKOUT0_2:
217 return AXI_CLKGEN_V1_REG_CLK_OUT2;
218 case MMCM_REG_CLK_FB1:
219 return AXI_CLKGEN_V1_REG_CLK_FB1;
220 case MMCM_REG_CLK_FB2:
221 return AXI_CLKGEN_V1_REG_CLK_FB2;
222 case MMCM_REG_CLK_DIV:
223 return AXI_CLKGEN_V1_REG_CLK_DIV;
224 case MMCM_REG_LOCK1:
225 return AXI_CLKGEN_V1_REG_LOCK1;
226 case MMCM_REG_LOCK2:
227 return AXI_CLKGEN_V1_REG_LOCK2;
228 case MMCM_REG_LOCK3:
229 return AXI_CLKGEN_V1_REG_LOCK3;
230 case MMCM_REG_FILTER1:
231 return AXI_CLKGEN_V1_REG_FILTER1;
232 case MMCM_REG_FILTER2:
233 return AXI_CLKGEN_V1_REG_FILTER2;
234 default:
235 return 0;
236 }
237}
238
239static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen,
240 unsigned int reg, unsigned int val, unsigned int mask)
241{
242 reg = axi_clkgen_v1_map_mmcm_reg(reg);
243 if (reg == 0)
244 return -EINVAL;
245
246 axi_clkgen_write(axi_clkgen, reg, val);
247
248 return 0;
249}
250
251static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen,
252 unsigned int reg, unsigned int *val)
253{
254 reg = axi_clkgen_v1_map_mmcm_reg(reg);
255 if (reg == 0)
256 return -EINVAL;
257
258 axi_clkgen_read(axi_clkgen, reg, val);
259
260 return 0;
261}
262
263static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen,
264 bool enable)
265{
266 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable);
267}
268
269static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = {
270 .write = axi_clkgen_v1_mmcm_write,
271 .read = axi_clkgen_v1_mmcm_read,
272 .enable = axi_clkgen_v1_mmcm_enable,
273};
274
275static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen)
276{
277 unsigned int timeout = 10000;
278 unsigned int val;
279
280 do {
281 axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_STATUS, &val);
282 } while ((val & AXI_CLKGEN_V2_DRP_STATUS_BUSY) && --timeout);
283
284 if (val & AXI_CLKGEN_V2_DRP_STATUS_BUSY)
285 return -EIO;
286
287 return val & 0xffff;
288}
289
290static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen,
291 unsigned int reg, unsigned int *val)
292{
293 unsigned int reg_val;
294 int ret;
295
296 ret = axi_clkgen_wait_non_busy(axi_clkgen);
297 if (ret < 0)
298 return ret;
299
300 reg_val = AXI_CLKGEN_V2_DRP_CNTRL_SEL | AXI_CLKGEN_V2_DRP_CNTRL_READ;
301 reg_val |= (reg << 16);
302
303 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
304
305 ret = axi_clkgen_wait_non_busy(axi_clkgen);
306 if (ret < 0)
307 return ret;
308
309 *val = ret;
310
311 return 0;
312}
313
314static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen,
315 unsigned int reg, unsigned int val, unsigned int mask)
316{
317 unsigned int reg_val = 0;
318 int ret;
319
320 ret = axi_clkgen_wait_non_busy(axi_clkgen);
321 if (ret < 0)
322 return ret;
323
324 if (mask != 0xffff) {
325 axi_clkgen_v2_mmcm_read(axi_clkgen, reg, &reg_val);
326 reg_val &= ~mask;
327 }
328
329 reg_val |= AXI_CLKGEN_V2_DRP_CNTRL_SEL | (reg << 16) | (val & mask);
330
331 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_DRP_CNTRL, reg_val);
332
333 return 0;
334}
335
336static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen,
337 bool enable)
338{
339 unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE;
340
341 if (enable)
342 val |= AXI_CLKGEN_V2_RESET_MMCM_ENABLE;
343
344 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val);
345}
346
347static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = {
348 .write = axi_clkgen_v2_mmcm_write,
349 .read = axi_clkgen_v2_mmcm_read,
350 .enable = axi_clkgen_v2_mmcm_enable,
351};
352
159static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) 353static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
160{ 354{
161 return container_of(clk_hw, struct axi_clkgen, clk_hw); 355 return container_of(clk_hw, struct axi_clkgen, clk_hw);
@@ -184,33 +378,29 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
184 filter = axi_clkgen_lookup_filter(m - 1); 378 filter = axi_clkgen_lookup_filter(m - 1);
185 lock = axi_clkgen_lookup_lock(m - 1); 379 lock = axi_clkgen_lookup_lock(m - 1);
186 380
187 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0);
188
189 axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount); 381 axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
190 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, 382 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_1,
191 (high << 6) | low); 383 (high << 6) | low, 0xefff);
192 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2, 384 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_2,
193 (edge << 7) | (nocount << 6)); 385 (edge << 7) | (nocount << 6), 0x03ff);
194 386
195 axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount); 387 axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
196 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, 388 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV,
197 (edge << 13) | (nocount << 12) | (high << 6) | low); 389 (edge << 13) | (nocount << 12) | (high << 6) | low, 0x3fff);
198 390
199 axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount); 391 axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
200 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, 392 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB1,
201 (high << 6) | low); 393 (high << 6) | low, 0xefff);
202 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2, 394 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB2,
203 (edge << 7) | (nocount << 6)); 395 (edge << 7) | (nocount << 6), 0x03ff);
204 396
205 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff); 397 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff);
206 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2, 398 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2,
207 (((lock >> 16) & 0x1f) << 10) | 0x1); 399 (((lock >> 16) & 0x1f) << 10) | 0x1, 0x7fff);
208 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3, 400 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK3,
209 (((lock >> 24) & 0x1f) << 10) | 0x3e9); 401 (((lock >> 24) & 0x1f) << 10) | 0x3e9, 0x7fff);
210 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16); 402 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER1, filter >> 16, 0x9900);
211 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter); 403 axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_FILTER2, filter, 0x9900);
212
213 axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1);
214 404
215 return 0; 405 return 0;
216} 406}
@@ -236,11 +426,11 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
236 unsigned int reg; 426 unsigned int reg;
237 unsigned long long tmp; 427 unsigned long long tmp;
238 428
239 axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, &reg); 429 axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, &reg);
240 dout = (reg & 0x3f) + ((reg >> 6) & 0x3f); 430 dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
241 axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, &reg); 431 axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &reg);
242 d = (reg & 0x3f) + ((reg >> 6) & 0x3f); 432 d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
243 axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, &reg); 433 axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, &reg);
244 m = (reg & 0x3f) + ((reg >> 6) & 0x3f); 434 m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
245 435
246 if (d == 0 || dout == 0) 436 if (d == 0 || dout == 0)
@@ -255,14 +445,45 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
255 return tmp; 445 return tmp;
256} 446}
257 447
448static int axi_clkgen_enable(struct clk_hw *clk_hw)
449{
450 struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
451
452 axi_clkgen_mmcm_enable(axi_clkgen, true);
453
454 return 0;
455}
456
457static void axi_clkgen_disable(struct clk_hw *clk_hw)
458{
459 struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
460
461 axi_clkgen_mmcm_enable(axi_clkgen, false);
462}
463
258static const struct clk_ops axi_clkgen_ops = { 464static const struct clk_ops axi_clkgen_ops = {
259 .recalc_rate = axi_clkgen_recalc_rate, 465 .recalc_rate = axi_clkgen_recalc_rate,
260 .round_rate = axi_clkgen_round_rate, 466 .round_rate = axi_clkgen_round_rate,
261 .set_rate = axi_clkgen_set_rate, 467 .set_rate = axi_clkgen_set_rate,
468 .enable = axi_clkgen_enable,
469 .disable = axi_clkgen_disable,
262}; 470};
263 471
472static const struct of_device_id axi_clkgen_ids[] = {
473 {
474 .compatible = "adi,axi-clkgen-1.00.a",
475 .data = &axi_clkgen_v1_mmcm_ops
476 }, {
477 .compatible = "adi,axi-clkgen-2.00.a",
478 .data = &axi_clkgen_v2_mmcm_ops,
479 },
480 { },
481};
482MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
483
264static int axi_clkgen_probe(struct platform_device *pdev) 484static int axi_clkgen_probe(struct platform_device *pdev)
265{ 485{
486 const struct of_device_id *id;
266 struct axi_clkgen *axi_clkgen; 487 struct axi_clkgen *axi_clkgen;
267 struct clk_init_data init; 488 struct clk_init_data init;
268 const char *parent_name; 489 const char *parent_name;
@@ -270,10 +491,19 @@ static int axi_clkgen_probe(struct platform_device *pdev)
270 struct resource *mem; 491 struct resource *mem;
271 struct clk *clk; 492 struct clk *clk;
272 493
494 if (!pdev->dev.of_node)
495 return -ENODEV;
496
497 id = of_match_node(axi_clkgen_ids, pdev->dev.of_node);
498 if (!id)
499 return -ENODEV;
500
273 axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL); 501 axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
274 if (!axi_clkgen) 502 if (!axi_clkgen)
275 return -ENOMEM; 503 return -ENOMEM;
276 504
505 axi_clkgen->mmcm_ops = id->data;
506
277 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 507 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
278 axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); 508 axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
279 if (IS_ERR(axi_clkgen->base)) 509 if (IS_ERR(axi_clkgen->base))
@@ -289,10 +519,12 @@ static int axi_clkgen_probe(struct platform_device *pdev)
289 519
290 init.name = clk_name; 520 init.name = clk_name;
291 init.ops = &axi_clkgen_ops; 521 init.ops = &axi_clkgen_ops;
292 init.flags = 0; 522 init.flags = CLK_SET_RATE_GATE;
293 init.parent_names = &parent_name; 523 init.parent_names = &parent_name;
294 init.num_parents = 1; 524 init.num_parents = 1;
295 525
526 axi_clkgen_mmcm_enable(axi_clkgen, false);
527
296 axi_clkgen->clk_hw.init = &init; 528 axi_clkgen->clk_hw.init = &init;
297 clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw); 529 clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
298 if (IS_ERR(clk)) 530 if (IS_ERR(clk))
@@ -309,12 +541,6 @@ static int axi_clkgen_remove(struct platform_device *pdev)
309 return 0; 541 return 0;
310} 542}
311 543
312static const struct of_device_id axi_clkgen_ids[] = {
313 { .compatible = "adi,axi-clkgen-1.00.a" },
314 { },
315};
316MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
317
318static struct platform_driver axi_clkgen_driver = { 544static struct platform_driver axi_clkgen_driver = {
319 .driver = { 545 .driver = {
320 .name = "adi-axi-clkgen", 546 .name = "adi-axi-clkgen",
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 5543b7df8e16..ec22112e569f 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -24,7 +24,7 @@
24 * Traits of this clock: 24 * Traits of this clock:
25 * prepare - clk_prepare only ensures that parents are prepared 25 * prepare - clk_prepare only ensures that parents are prepared
26 * enable - clk_enable only ensures that parents are enabled 26 * enable - clk_enable only ensures that parents are enabled
27 * rate - rate is adjustable. clk->rate = parent->rate / divisor 27 * rate - rate is adjustable. clk->rate = DIV_ROUND_UP(parent->rate / divisor)
28 * parent - fixed parent. No clk_set_parent support 28 * parent - fixed parent. No clk_set_parent support
29 */ 29 */
30 30
@@ -115,7 +115,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
115 return parent_rate; 115 return parent_rate;
116 } 116 }
117 117
118 return parent_rate / div; 118 return DIV_ROUND_UP(parent_rate, div);
119} 119}
120 120
121/* 121/*
@@ -185,7 +185,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
185 } 185 }
186 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 186 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
187 MULT_ROUND_UP(rate, i)); 187 MULT_ROUND_UP(rate, i));
188 now = parent_rate / i; 188 now = DIV_ROUND_UP(parent_rate, i);
189 if (now <= rate && now > best) { 189 if (now <= rate && now > best) {
190 bestdiv = i; 190 bestdiv = i;
191 best = now; 191 best = now;
@@ -207,7 +207,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
207 int div; 207 int div;
208 div = clk_divider_bestdiv(hw, rate, prate); 208 div = clk_divider_bestdiv(hw, rate, prate);
209 209
210 return *prate / div; 210 return DIV_ROUND_UP(*prate, div);
211} 211}
212 212
213static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, 213static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -218,7 +218,7 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
218 unsigned long flags = 0; 218 unsigned long flags = 0;
219 u32 val; 219 u32 val;
220 220
221 div = parent_rate / rate; 221 div = DIV_ROUND_UP(parent_rate, rate);
222 value = _get_val(divider, div); 222 value = _get_val(divider, div);
223 223
224 if (value > div_mask(divider)) 224 if (value > div_mask(divider))
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
new file mode 100644
index 000000000000..30a3b6999e10
--- /dev/null
+++ b/drivers/clk/clk-moxart.c
@@ -0,0 +1,97 @@
1/*
2 * MOXA ART SoCs clock driver.
3 *
4 * Copyright (C) 2013 Jonas Jensen
5 *
6 * Jonas Jensen <jonas.jensen@gmail.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/clk-provider.h>
14#include <linux/io.h>
15#include <linux/of_address.h>
16#include <linux/clkdev.h>
17
18void __init moxart_of_pll_clk_init(struct device_node *node)
19{
20 static void __iomem *base;
21 struct clk *clk, *ref_clk;
22 unsigned int mul;
23 const char *name = node->name;
24 const char *parent_name;
25
26 of_property_read_string(node, "clock-output-names", &name);
27 parent_name = of_clk_get_parent_name(node, 0);
28
29 base = of_iomap(node, 0);
30 if (!base) {
31 pr_err("%s: of_iomap failed\n", node->full_name);
32 return;
33 }
34
35 mul = readl(base + 0x30) >> 3 & 0x3f;
36 iounmap(base);
37
38 ref_clk = of_clk_get(node, 0);
39 if (IS_ERR(ref_clk)) {
40 pr_err("%s: of_clk_get failed\n", node->full_name);
41 return;
42 }
43
44 clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
45 if (IS_ERR(clk)) {
46 pr_err("%s: failed to register clock\n", node->full_name);
47 return;
48 }
49
50 clk_register_clkdev(clk, NULL, name);
51 of_clk_add_provider(node, of_clk_src_simple_get, clk);
52}
53CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
54 moxart_of_pll_clk_init);
55
56void __init moxart_of_apb_clk_init(struct device_node *node)
57{
58 static void __iomem *base;
59 struct clk *clk, *pll_clk;
60 unsigned int div, val;
61 unsigned int div_idx[] = { 2, 3, 4, 6, 8};
62 const char *name = node->name;
63 const char *parent_name;
64
65 of_property_read_string(node, "clock-output-names", &name);
66 parent_name = of_clk_get_parent_name(node, 0);
67
68 base = of_iomap(node, 0);
69 if (!base) {
70 pr_err("%s: of_iomap failed\n", node->full_name);
71 return;
72 }
73
74 val = readl(base + 0xc) >> 4 & 0x7;
75 iounmap(base);
76
77 if (val > 4)
78 val = 0;
79 div = div_idx[val] * 2;
80
81 pll_clk = of_clk_get(node, 0);
82 if (IS_ERR(pll_clk)) {
83 pr_err("%s: of_clk_get failed\n", node->full_name);
84 return;
85 }
86
87 clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
88 if (IS_ERR(clk)) {
89 pr_err("%s: failed to register clock\n", node->full_name);
90 return;
91 }
92
93 clk_register_clkdev(clk, NULL, name);
94 of_clk_add_provider(node, of_clk_src_simple_get, clk);
95}
96CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
97 moxart_of_apb_clk_init);
diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c
index 6a934a5296bd..05e04ce0f148 100644
--- a/drivers/clk/clk-nomadik.c
+++ b/drivers/clk/clk-nomadik.c
@@ -494,6 +494,9 @@ static const struct file_operations nomadik_src_clk_debugfs_ops = {
494 494
495static int __init nomadik_src_clk_init_debugfs(void) 495static int __init nomadik_src_clk_init_debugfs(void)
496{ 496{
497 /* Vital for multiplatform */
498 if (!src_base)
499 return -ENODEV;
497 src_pcksr0_boot = readl(src_base + SRC_PCKSR0); 500 src_pcksr0_boot = readl(src_base + SRC_PCKSR0);
498 src_pcksr1_boot = readl(src_base + SRC_PCKSR1); 501 src_pcksr1_boot = readl(src_base + SRC_PCKSR1);
499 debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO, 502 debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO,
diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c
index 00a3abe103a5..f4c1f0881b6c 100644
--- a/drivers/clk/clk-s2mps11.c
+++ b/drivers/clk/clk-s2mps11.c
@@ -27,6 +27,7 @@
27#include <linux/clk-provider.h> 27#include <linux/clk-provider.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/mfd/samsung/s2mps11.h> 29#include <linux/mfd/samsung/s2mps11.h>
30#include <linux/mfd/samsung/s5m8767.h>
30#include <linux/mfd/samsung/core.h> 31#include <linux/mfd/samsung/core.h>
31 32
32#define s2mps11_name(a) (a->hw.init->name) 33#define s2mps11_name(a) (a->hw.init->name)
@@ -48,6 +49,7 @@ struct s2mps11_clk {
48 struct clk_lookup *lookup; 49 struct clk_lookup *lookup;
49 u32 mask; 50 u32 mask;
50 bool enabled; 51 bool enabled;
52 unsigned int reg;
51}; 53};
52 54
53static struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw) 55static struct s2mps11_clk *to_s2mps11_clk(struct clk_hw *hw)
@@ -61,7 +63,7 @@ static int s2mps11_clk_prepare(struct clk_hw *hw)
61 int ret; 63 int ret;
62 64
63 ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, 65 ret = regmap_update_bits(s2mps11->iodev->regmap_pmic,
64 S2MPS11_REG_RTC_CTRL, 66 s2mps11->reg,
65 s2mps11->mask, s2mps11->mask); 67 s2mps11->mask, s2mps11->mask);
66 if (!ret) 68 if (!ret)
67 s2mps11->enabled = true; 69 s2mps11->enabled = true;
@@ -74,7 +76,7 @@ static void s2mps11_clk_unprepare(struct clk_hw *hw)
74 struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw); 76 struct s2mps11_clk *s2mps11 = to_s2mps11_clk(hw);
75 int ret; 77 int ret;
76 78
77 ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, S2MPS11_REG_RTC_CTRL, 79 ret = regmap_update_bits(s2mps11->iodev->regmap_pmic, s2mps11->reg,
78 s2mps11->mask, ~s2mps11->mask); 80 s2mps11->mask, ~s2mps11->mask);
79 81
80 if (!ret) 82 if (!ret)
@@ -155,6 +157,7 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
155 struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); 157 struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
156 struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; 158 struct s2mps11_clk *s2mps11_clks, *s2mps11_clk;
157 struct device_node *clk_np = NULL; 159 struct device_node *clk_np = NULL;
160 unsigned int s2mps11_reg;
158 int i, ret = 0; 161 int i, ret = 0;
159 u32 val; 162 u32 val;
160 163
@@ -169,13 +172,26 @@ static int s2mps11_clk_probe(struct platform_device *pdev)
169 if (IS_ERR(clk_np)) 172 if (IS_ERR(clk_np))
170 return PTR_ERR(clk_np); 173 return PTR_ERR(clk_np);
171 174
175 switch(platform_get_device_id(pdev)->driver_data) {
176 case S2MPS11X:
177 s2mps11_reg = S2MPS11_REG_RTC_CTRL;
178 break;
179 case S5M8767X:
180 s2mps11_reg = S5M8767_REG_CTRL1;
181 break;
182 default:
183 dev_err(&pdev->dev, "Invalid device type\n");
184 return -EINVAL;
185 };
186
172 for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { 187 for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) {
173 s2mps11_clk->iodev = iodev; 188 s2mps11_clk->iodev = iodev;
174 s2mps11_clk->hw.init = &s2mps11_clks_init[i]; 189 s2mps11_clk->hw.init = &s2mps11_clks_init[i];
175 s2mps11_clk->mask = 1 << i; 190 s2mps11_clk->mask = 1 << i;
191 s2mps11_clk->reg = s2mps11_reg;
176 192
177 ret = regmap_read(s2mps11_clk->iodev->regmap_pmic, 193 ret = regmap_read(s2mps11_clk->iodev->regmap_pmic,
178 S2MPS11_REG_RTC_CTRL, &val); 194 s2mps11_clk->reg, &val);
179 if (ret < 0) 195 if (ret < 0)
180 goto err_reg; 196 goto err_reg;
181 197
@@ -241,7 +257,8 @@ static int s2mps11_clk_remove(struct platform_device *pdev)
241} 257}
242 258
243static const struct platform_device_id s2mps11_clk_id[] = { 259static const struct platform_device_id s2mps11_clk_id[] = {
244 { "s2mps11-clk", 0}, 260 { "s2mps11-clk", S2MPS11X},
261 { "s5m8767-clk", S5M8767X},
245 { }, 262 { },
246}; 263};
247MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); 264MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 5517944495d8..895b3d204e22 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1339,8 +1339,11 @@ static int __clk_speculate_rates(struct clk *clk, unsigned long parent_rate)
1339 if (clk->notifier_count) 1339 if (clk->notifier_count)
1340 ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate); 1340 ret = __clk_notify(clk, PRE_RATE_CHANGE, clk->rate, new_rate);
1341 1341
1342 if (ret & NOTIFY_STOP_MASK) 1342 if (ret & NOTIFY_STOP_MASK) {
1343 pr_debug("%s: clk notifier callback for clock %s aborted with error %d\n",
1344 __func__, clk->name, ret);
1343 goto out; 1345 goto out;
1346 }
1344 1347
1345 hlist_for_each_entry(child, &clk->children, child_node) { 1348 hlist_for_each_entry(child, &clk->children, child_node) {
1346 ret = __clk_speculate_rates(child, new_rate); 1349 ret = __clk_speculate_rates(child, new_rate);
@@ -2226,24 +2229,25 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
2226 */ 2229 */
2227int __clk_get(struct clk *clk) 2230int __clk_get(struct clk *clk)
2228{ 2231{
2229 if (clk && !try_module_get(clk->owner)) 2232 if (clk) {
2230 return 0; 2233 if (!try_module_get(clk->owner))
2234 return 0;
2231 2235
2232 kref_get(&clk->ref); 2236 kref_get(&clk->ref);
2237 }
2233 return 1; 2238 return 1;
2234} 2239}
2235 2240
2236void __clk_put(struct clk *clk) 2241void __clk_put(struct clk *clk)
2237{ 2242{
2238 if (WARN_ON_ONCE(IS_ERR(clk))) 2243 if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
2239 return; 2244 return;
2240 2245
2241 clk_prepare_lock(); 2246 clk_prepare_lock();
2242 kref_put(&clk->ref, __clk_release); 2247 kref_put(&clk->ref, __clk_release);
2243 clk_prepare_unlock(); 2248 clk_prepare_unlock();
2244 2249
2245 if (clk) 2250 module_put(clk->owner);
2246 module_put(clk->owner);
2247} 2251}
2248 2252
2249/*** clk rate change notifiers ***/ 2253/*** clk rate change notifiers ***/
@@ -2259,20 +2263,11 @@ void __clk_put(struct clk *clk)
2259 * re-enter into the clk framework by calling any top-level clk APIs; 2263 * re-enter into the clk framework by calling any top-level clk APIs;
2260 * this will cause a nested prepare_lock mutex. 2264 * this will cause a nested prepare_lock mutex.
2261 * 2265 *
2262 * Pre-change notifier callbacks will be passed the current, pre-change 2266 * In all notification cases cases (pre, post and abort rate change) the
2263 * rate of the clk via struct clk_notifier_data.old_rate. The new, 2267 * original clock rate is passed to the callback via struct
2264 * post-change rate of the clk is passed via struct 2268 * clk_notifier_data.old_rate and the new frequency is passed via struct
2265 * clk_notifier_data.new_rate. 2269 * clk_notifier_data.new_rate.
2266 * 2270 *
2267 * Post-change notifiers will pass the now-current, post-change rate of
2268 * the clk in both struct clk_notifier_data.old_rate and struct
2269 * clk_notifier_data.new_rate.
2270 *
2271 * Abort-change notifiers are effectively the opposite of pre-change
2272 * notifiers: the original pre-change clk rate is passed in via struct
2273 * clk_notifier_data.new_rate and the failed post-change rate is passed
2274 * in via struct clk_notifier_data.old_rate.
2275 *
2276 * clk_notifier_register() must be called from non-atomic context. 2271 * clk_notifier_register() must be called from non-atomic context.
2277 * Returns -EINVAL if called with null arguments, -ENOMEM upon 2272 * Returns -EINVAL if called with null arguments, -ENOMEM upon
2278 * allocation failure; otherwise, passes along the return value of 2273 * allocation failure; otherwise, passes along the return value of
@@ -2472,7 +2467,7 @@ EXPORT_SYMBOL_GPL(of_clk_del_provider);
2472struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec) 2467struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec)
2473{ 2468{
2474 struct of_clk_provider *provider; 2469 struct of_clk_provider *provider;
2475 struct clk *clk = ERR_PTR(-ENOENT); 2470 struct clk *clk = ERR_PTR(-EPROBE_DEFER);
2476 2471
2477 /* Check if we have such a provider in our array */ 2472 /* Check if we have such a provider in our array */
2478 list_for_each_entry(provider, &of_clk_providers, link) { 2473 list_for_each_entry(provider, &of_clk_providers, link) {
@@ -2505,8 +2500,12 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_count);
2505const char *of_clk_get_parent_name(struct device_node *np, int index) 2500const char *of_clk_get_parent_name(struct device_node *np, int index)
2506{ 2501{
2507 struct of_phandle_args clkspec; 2502 struct of_phandle_args clkspec;
2503 struct property *prop;
2508 const char *clk_name; 2504 const char *clk_name;
2505 const __be32 *vp;
2506 u32 pv;
2509 int rc; 2507 int rc;
2508 int count;
2510 2509
2511 if (index < 0) 2510 if (index < 0)
2512 return NULL; 2511 return NULL;
@@ -2516,8 +2515,22 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
2516 if (rc) 2515 if (rc)
2517 return NULL; 2516 return NULL;
2518 2517
2518 index = clkspec.args_count ? clkspec.args[0] : 0;
2519 count = 0;
2520
2521 /* if there is an indices property, use it to transfer the index
2522 * specified into an array offset for the clock-output-names property.
2523 */
2524 of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) {
2525 if (index == pv) {
2526 index = count;
2527 break;
2528 }
2529 count++;
2530 }
2531
2519 if (of_property_read_string_index(clkspec.np, "clock-output-names", 2532 if (of_property_read_string_index(clkspec.np, "clock-output-names",
2520 clkspec.args_count ? clkspec.args[0] : 0, 2533 index,
2521 &clk_name) < 0) 2534 &clk_name) < 0)
2522 clk_name = clkspec.np->name; 2535 clk_name = clkspec.np->name;
2523 2536
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index 48f67218247c..a360b2eca5cb 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -167,6 +167,8 @@ struct clk *clk_get(struct device *dev, const char *con_id)
167 clk = of_clk_get_by_name(dev->of_node, con_id); 167 clk = of_clk_get_by_name(dev->of_node, con_id);
168 if (!IS_ERR(clk)) 168 if (!IS_ERR(clk))
169 return clk; 169 return clk;
170 if (PTR_ERR(clk) == -EPROBE_DEFER)
171 return clk;
170 } 172 }
171 173
172 return clk_get_sys(dev_id, con_id); 174 return clk_get_sys(dev_id, con_id);
diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c
index f24ad6a3a797..38faa469d288 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -240,3 +240,277 @@ static void __init hi3620_clk_init(struct device_node *np)
240 base); 240 base);
241} 241}
242CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init); 242CLK_OF_DECLARE(hi3620_clk, "hisilicon,hi3620-clock", hi3620_clk_init);
243
244struct hisi_mmc_clock {
245 unsigned int id;
246 const char *name;
247 const char *parent_name;
248 unsigned long flags;
249 u32 clken_reg;
250 u32 clken_bit;
251 u32 div_reg;
252 u32 div_off;
253 u32 div_bits;
254 u32 drv_reg;
255 u32 drv_off;
256 u32 drv_bits;
257 u32 sam_reg;
258 u32 sam_off;
259 u32 sam_bits;
260};
261
262struct clk_mmc {
263 struct clk_hw hw;
264 u32 id;
265 void __iomem *clken_reg;
266 u32 clken_bit;
267 void __iomem *div_reg;
268 u32 div_off;
269 u32 div_bits;
270 void __iomem *drv_reg;
271 u32 drv_off;
272 u32 drv_bits;
273 void __iomem *sam_reg;
274 u32 sam_off;
275 u32 sam_bits;
276};
277
278#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw)
279
280static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = {
281 { HI3620_SD_CIUCLK, "sd_bclk1", "sd_clk", CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4},
282 { HI3620_MMC_CIUCLK1, "mmc_bclk1", "mmc_clk1", CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4},
283 { HI3620_MMC_CIUCLK2, "mmc_bclk2", "mmc_clk2", CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4},
284 { HI3620_MMC_CIUCLK3, "mmc_bclk3", "mmc_clk3", CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4},
285};
286
287static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw,
288 unsigned long parent_rate)
289{
290 switch (parent_rate) {
291 case 26000000:
292 return 13000000;
293 case 180000000:
294 return 25000000;
295 case 360000000:
296 return 50000000;
297 case 720000000:
298 return 100000000;
299 case 1440000000:
300 return 180000000;
301 default:
302 return parent_rate;
303 }
304}
305
306static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate,
307 unsigned long *best_parent_rate,
308 struct clk **best_parent_p)
309{
310 struct clk_mmc *mclk = to_mmc(hw);
311 unsigned long best = 0;
312
313 if ((rate <= 13000000) && (mclk->id == HI3620_MMC_CIUCLK1)) {
314 rate = 13000000;
315 best = 26000000;
316 } else if (rate <= 26000000) {
317 rate = 25000000;
318 best = 180000000;
319 } else if (rate <= 52000000) {
320 rate = 50000000;
321 best = 360000000;
322 } else if (rate <= 100000000) {
323 rate = 100000000;
324 best = 720000000;
325 } else {
326 /* max is 180M */
327 rate = 180000000;
328 best = 1440000000;
329 }
330 *best_parent_rate = best;
331 return rate;
332}
333
334static u32 mmc_clk_delay(u32 val, u32 para, u32 off, u32 len)
335{
336 u32 i;
337
338 if (para >= 0) {
339 for (i = 0; i < len; i++) {
340 if (para % 2)
341 val |= 1 << (off + i);
342 else
343 val &= ~(1 << (off + i));
344 para = para >> 1;
345 }
346 }
347 return val;
348}
349
350static int mmc_clk_set_timing(struct clk_hw *hw, unsigned long rate)
351{
352 struct clk_mmc *mclk = to_mmc(hw);
353 unsigned long flags;
354 u32 sam, drv, div, val;
355 static DEFINE_SPINLOCK(mmc_clk_lock);
356
357 switch (rate) {
358 case 13000000:
359 sam = 3;
360 drv = 1;
361 div = 1;
362 break;
363 case 25000000:
364 sam = 13;
365 drv = 6;
366 div = 6;
367 break;
368 case 50000000:
369 sam = 3;
370 drv = 6;
371 div = 6;
372 break;
373 case 100000000:
374 sam = 6;
375 drv = 4;
376 div = 6;
377 break;
378 case 180000000:
379 sam = 6;
380 drv = 4;
381 div = 7;
382 break;
383 default:
384 return -EINVAL;
385 }
386
387 spin_lock_irqsave(&mmc_clk_lock, flags);
388
389 val = readl_relaxed(mclk->clken_reg);
390 val &= ~(1 << mclk->clken_bit);
391 writel_relaxed(val, mclk->clken_reg);
392
393 val = readl_relaxed(mclk->sam_reg);
394 val = mmc_clk_delay(val, sam, mclk->sam_off, mclk->sam_bits);
395 writel_relaxed(val, mclk->sam_reg);
396
397 val = readl_relaxed(mclk->drv_reg);
398 val = mmc_clk_delay(val, drv, mclk->drv_off, mclk->drv_bits);
399 writel_relaxed(val, mclk->drv_reg);
400
401 val = readl_relaxed(mclk->div_reg);
402 val = mmc_clk_delay(val, div, mclk->div_off, mclk->div_bits);
403 writel_relaxed(val, mclk->div_reg);
404
405 val = readl_relaxed(mclk->clken_reg);
406 val |= 1 << mclk->clken_bit;
407 writel_relaxed(val, mclk->clken_reg);
408
409 spin_unlock_irqrestore(&mmc_clk_lock, flags);
410
411 return 0;
412}
413
414static int mmc_clk_prepare(struct clk_hw *hw)
415{
416 struct clk_mmc *mclk = to_mmc(hw);
417 unsigned long rate;
418
419 if (mclk->id == HI3620_MMC_CIUCLK1)
420 rate = 13000000;
421 else
422 rate = 25000000;
423
424 return mmc_clk_set_timing(hw, rate);
425}
426
427static int mmc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
428 unsigned long parent_rate)
429{
430 return mmc_clk_set_timing(hw, rate);
431}
432
433static struct clk_ops clk_mmc_ops = {
434 .prepare = mmc_clk_prepare,
435 .determine_rate = mmc_clk_determine_rate,
436 .set_rate = mmc_clk_set_rate,
437 .recalc_rate = mmc_clk_recalc_rate,
438};
439
440static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
441 void __iomem *base, struct device_node *np)
442{
443 struct clk_mmc *mclk;
444 struct clk *clk;
445 struct clk_init_data init;
446
447 mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
448 if (!mclk) {
449 pr_err("%s: fail to allocate mmc clk\n", __func__);
450 return ERR_PTR(-ENOMEM);
451 }
452
453 init.name = mmc_clk->name;
454 init.ops = &clk_mmc_ops;
455 init.flags = mmc_clk->flags | CLK_IS_BASIC;
456 init.parent_names = (mmc_clk->parent_name ? &mmc_clk->parent_name : NULL);
457 init.num_parents = (mmc_clk->parent_name ? 1 : 0);
458 mclk->hw.init = &init;
459
460 mclk->id = mmc_clk->id;
461 mclk->clken_reg = base + mmc_clk->clken_reg;
462 mclk->clken_bit = mmc_clk->clken_bit;
463 mclk->div_reg = base + mmc_clk->div_reg;
464 mclk->div_off = mmc_clk->div_off;
465 mclk->div_bits = mmc_clk->div_bits;
466 mclk->drv_reg = base + mmc_clk->drv_reg;
467 mclk->drv_off = mmc_clk->drv_off;
468 mclk->drv_bits = mmc_clk->drv_bits;
469 mclk->sam_reg = base + mmc_clk->sam_reg;
470 mclk->sam_off = mmc_clk->sam_off;
471 mclk->sam_bits = mmc_clk->sam_bits;
472
473 clk = clk_register(NULL, &mclk->hw);
474 if (WARN_ON(IS_ERR(clk)))
475 kfree(mclk);
476 return clk;
477}
478
479static void __init hi3620_mmc_clk_init(struct device_node *node)
480{
481 void __iomem *base;
482 int i, num = ARRAY_SIZE(hi3620_mmc_clks);
483 struct clk_onecell_data *clk_data;
484
485 if (!node) {
486 pr_err("failed to find pctrl node in DTS\n");
487 return;
488 }
489
490 base = of_iomap(node, 0);
491 if (!base) {
492 pr_err("failed to map pctrl\n");
493 return;
494 }
495
496 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
497 if (WARN_ON(!clk_data))
498 return;
499
500 clk_data->clks = kzalloc(sizeof(struct clk *) * num, GFP_KERNEL);
501 if (!clk_data->clks) {
502 pr_err("%s: fail to allocate mmc clk\n", __func__);
503 return;
504 }
505
506 for (i = 0; i < num; i++) {
507 struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
508 clk_data->clks[mmc_clk->id] =
509 hisi_register_clk_mmc(mmc_clk, base, node);
510 }
511
512 clk_data->clk_num = num;
513 of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
514}
515
516CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", hi3620_mmc_clk_init);
diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c
index 17a598398a53..86f1e362eafb 100644
--- a/drivers/clk/keystone/gate.c
+++ b/drivers/clk/keystone/gate.c
@@ -179,6 +179,7 @@ static struct clk *clk_register_psc(struct device *dev,
179 179
180 init.name = name; 180 init.name = name;
181 init.ops = &clk_psc_ops; 181 init.ops = &clk_psc_ops;
182 init.flags = 0;
182 init.parent_names = (parent_name ? &parent_name : NULL); 183 init.parent_names = (parent_name ? &parent_name : NULL);
183 init.num_parents = (parent_name ? 1 : 0); 184 init.num_parents = (parent_name ? 1 : 0);
184 185
diff --git a/drivers/clk/mvebu/armada-370.c b/drivers/clk/mvebu/armada-370.c
index 81a202d12a7a..bef198a83863 100644
--- a/drivers/clk/mvebu/armada-370.c
+++ b/drivers/clk/mvebu/armada-370.c
@@ -141,13 +141,6 @@ static const struct coreclk_soc_desc a370_coreclks = {
141 .num_ratios = ARRAY_SIZE(a370_coreclk_ratios), 141 .num_ratios = ARRAY_SIZE(a370_coreclk_ratios),
142}; 142};
143 143
144static void __init a370_coreclk_init(struct device_node *np)
145{
146 mvebu_coreclk_setup(np, &a370_coreclks);
147}
148CLK_OF_DECLARE(a370_core_clk, "marvell,armada-370-core-clock",
149 a370_coreclk_init);
150
151/* 144/*
152 * Clock Gating Control 145 * Clock Gating Control
153 */ 146 */
@@ -168,9 +161,15 @@ static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = {
168 { } 161 { }
169}; 162};
170 163
171static void __init a370_clk_gating_init(struct device_node *np) 164static void __init a370_clk_init(struct device_node *np)
172{ 165{
173 mvebu_clk_gating_setup(np, a370_gating_desc); 166 struct device_node *cgnp =
167 of_find_compatible_node(NULL, NULL, "marvell,armada-370-gating-clock");
168
169 mvebu_coreclk_setup(np, &a370_coreclks);
170
171 if (cgnp)
172 mvebu_clk_gating_setup(cgnp, a370_gating_desc);
174} 173}
175CLK_OF_DECLARE(a370_clk_gating, "marvell,armada-370-gating-clock", 174CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init);
176 a370_clk_gating_init); 175
diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c
index 9922c4475aa8..b3094315a3c0 100644
--- a/drivers/clk/mvebu/armada-xp.c
+++ b/drivers/clk/mvebu/armada-xp.c
@@ -158,13 +158,6 @@ static const struct coreclk_soc_desc axp_coreclks = {
158 .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), 158 .num_ratios = ARRAY_SIZE(axp_coreclk_ratios),
159}; 159};
160 160
161static void __init axp_coreclk_init(struct device_node *np)
162{
163 mvebu_coreclk_setup(np, &axp_coreclks);
164}
165CLK_OF_DECLARE(axp_core_clk, "marvell,armada-xp-core-clock",
166 axp_coreclk_init);
167
168/* 161/*
169 * Clock Gating Control 162 * Clock Gating Control
170 */ 163 */
@@ -202,9 +195,14 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = {
202 { } 195 { }
203}; 196};
204 197
205static void __init axp_clk_gating_init(struct device_node *np) 198static void __init axp_clk_init(struct device_node *np)
206{ 199{
207 mvebu_clk_gating_setup(np, axp_gating_desc); 200 struct device_node *cgnp =
201 of_find_compatible_node(NULL, NULL, "marvell,armada-xp-gating-clock");
202
203 mvebu_coreclk_setup(np, &axp_coreclks);
204
205 if (cgnp)
206 mvebu_clk_gating_setup(cgnp, axp_gating_desc);
208} 207}
209CLK_OF_DECLARE(axp_clk_gating, "marvell,armada-xp-gating-clock", 208CLK_OF_DECLARE(axp_clk, "marvell,armada-xp-core-clock", axp_clk_init);
210 axp_clk_gating_init);
diff --git a/drivers/clk/mvebu/dove.c b/drivers/clk/mvebu/dove.c
index 38aee1e3f242..b8c2424ac926 100644
--- a/drivers/clk/mvebu/dove.c
+++ b/drivers/clk/mvebu/dove.c
@@ -154,12 +154,6 @@ static const struct coreclk_soc_desc dove_coreclks = {
154 .num_ratios = ARRAY_SIZE(dove_coreclk_ratios), 154 .num_ratios = ARRAY_SIZE(dove_coreclk_ratios),
155}; 155};
156 156
157static void __init dove_coreclk_init(struct device_node *np)
158{
159 mvebu_coreclk_setup(np, &dove_coreclks);
160}
161CLK_OF_DECLARE(dove_core_clk, "marvell,dove-core-clock", dove_coreclk_init);
162
163/* 157/*
164 * Clock Gating Control 158 * Clock Gating Control
165 */ 159 */
@@ -186,9 +180,14 @@ static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = {
186 { } 180 { }
187}; 181};
188 182
189static void __init dove_clk_gating_init(struct device_node *np) 183static void __init dove_clk_init(struct device_node *np)
190{ 184{
191 mvebu_clk_gating_setup(np, dove_gating_desc); 185 struct device_node *cgnp =
186 of_find_compatible_node(NULL, NULL, "marvell,dove-gating-clock");
187
188 mvebu_coreclk_setup(np, &dove_coreclks);
189
190 if (cgnp)
191 mvebu_clk_gating_setup(cgnp, dove_gating_desc);
192} 192}
193CLK_OF_DECLARE(dove_clk_gating, "marvell,dove-gating-clock", 193CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init);
194 dove_clk_gating_init);
diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c
index 2636a55f29f9..ddb666a86500 100644
--- a/drivers/clk/mvebu/kirkwood.c
+++ b/drivers/clk/mvebu/kirkwood.c
@@ -193,13 +193,6 @@ static const struct coreclk_soc_desc kirkwood_coreclks = {
193 .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), 193 .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios),
194}; 194};
195 195
196static void __init kirkwood_coreclk_init(struct device_node *np)
197{
198 mvebu_coreclk_setup(np, &kirkwood_coreclks);
199}
200CLK_OF_DECLARE(kirkwood_core_clk, "marvell,kirkwood-core-clock",
201 kirkwood_coreclk_init);
202
203static const struct coreclk_soc_desc mv88f6180_coreclks = { 196static const struct coreclk_soc_desc mv88f6180_coreclks = {
204 .get_tclk_freq = kirkwood_get_tclk_freq, 197 .get_tclk_freq = kirkwood_get_tclk_freq,
205 .get_cpu_freq = mv88f6180_get_cpu_freq, 198 .get_cpu_freq = mv88f6180_get_cpu_freq,
@@ -208,13 +201,6 @@ static const struct coreclk_soc_desc mv88f6180_coreclks = {
208 .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), 201 .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios),
209}; 202};
210 203
211static void __init mv88f6180_coreclk_init(struct device_node *np)
212{
213 mvebu_coreclk_setup(np, &mv88f6180_coreclks);
214}
215CLK_OF_DECLARE(mv88f6180_core_clk, "marvell,mv88f6180-core-clock",
216 mv88f6180_coreclk_init);
217
218/* 204/*
219 * Clock Gating Control 205 * Clock Gating Control
220 */ 206 */
@@ -239,9 +225,21 @@ static const struct clk_gating_soc_desc kirkwood_gating_desc[] __initconst = {
239 { } 225 { }
240}; 226};
241 227
242static void __init kirkwood_clk_gating_init(struct device_node *np) 228static void __init kirkwood_clk_init(struct device_node *np)
243{ 229{
244 mvebu_clk_gating_setup(np, kirkwood_gating_desc); 230 struct device_node *cgnp =
231 of_find_compatible_node(NULL, NULL, "marvell,kirkwood-gating-clock");
232
233
234 if (of_device_is_compatible(np, "marvell,mv88f6180-core-clock"))
235 mvebu_coreclk_setup(np, &mv88f6180_coreclks);
236 else
237 mvebu_coreclk_setup(np, &kirkwood_coreclks);
238
239 if (cgnp)
240 mvebu_clk_gating_setup(cgnp, kirkwood_gating_desc);
245} 241}
246CLK_OF_DECLARE(kirkwood_clk_gating, "marvell,kirkwood-gating-clock", 242CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock",
247 kirkwood_clk_gating_init); 243 kirkwood_clk_init);
244CLK_OF_DECLARE(mv88f6180_clk, "marvell,mv88f6180-core-clock",
245 kirkwood_clk_init);
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
index aac4756ec52e..f065f694cb65 100644
--- a/drivers/clk/shmobile/clk-div6.c
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -23,7 +23,7 @@
23#define CPG_DIV6_DIV_MASK 0x3f 23#define CPG_DIV6_DIV_MASK 0x3f
24 24
25/** 25/**
26 * struct div6_clock - MSTP gating clock 26 * struct div6_clock - CPG 6 bit divider clock
27 * @hw: handle between common and hardware-specific interfaces 27 * @hw: handle between common and hardware-specific interfaces
28 * @reg: IO-remapped register 28 * @reg: IO-remapped register
29 * @div: divisor value (1-64) 29 * @div: divisor value (1-64)
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
index a59ec217a124..dd272a0d1446 100644
--- a/drivers/clk/shmobile/clk-rcar-gen2.c
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -186,7 +186,7 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
186 const char *name) 186 const char *name)
187{ 187{
188 const struct clk_div_table *table = NULL; 188 const struct clk_div_table *table = NULL;
189 const char *parent_name = "main"; 189 const char *parent_name;
190 unsigned int shift; 190 unsigned int shift;
191 unsigned int mult = 1; 191 unsigned int mult = 1;
192 unsigned int div = 1; 192 unsigned int div = 1;
@@ -201,23 +201,31 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg,
201 * the multiplier value. 201 * the multiplier value.
202 */ 202 */
203 u32 value = clk_readl(cpg->reg + CPG_PLL0CR); 203 u32 value = clk_readl(cpg->reg + CPG_PLL0CR);
204 parent_name = "main";
204 mult = ((value >> 24) & ((1 << 7) - 1)) + 1; 205 mult = ((value >> 24) & ((1 << 7) - 1)) + 1;
205 } else if (!strcmp(name, "pll1")) { 206 } else if (!strcmp(name, "pll1")) {
207 parent_name = "main";
206 mult = config->pll1_mult / 2; 208 mult = config->pll1_mult / 2;
207 } else if (!strcmp(name, "pll3")) { 209 } else if (!strcmp(name, "pll3")) {
210 parent_name = "main";
208 mult = config->pll3_mult; 211 mult = config->pll3_mult;
209 } else if (!strcmp(name, "lb")) { 212 } else if (!strcmp(name, "lb")) {
213 parent_name = "pll1_div2";
210 div = cpg_mode & BIT(18) ? 36 : 24; 214 div = cpg_mode & BIT(18) ? 36 : 24;
211 } else if (!strcmp(name, "qspi")) { 215 } else if (!strcmp(name, "qspi")) {
216 parent_name = "pll1_div2";
212 div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) 217 div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2)
213 ? 16 : 20; 218 ? 8 : 10;
214 } else if (!strcmp(name, "sdh")) { 219 } else if (!strcmp(name, "sdh")) {
220 parent_name = "pll1_div2";
215 table = cpg_sdh_div_table; 221 table = cpg_sdh_div_table;
216 shift = 8; 222 shift = 8;
217 } else if (!strcmp(name, "sd0")) { 223 } else if (!strcmp(name, "sd0")) {
224 parent_name = "pll1_div2";
218 table = cpg_sd01_div_table; 225 table = cpg_sd01_div_table;
219 shift = 4; 226 shift = 4;
220 } else if (!strcmp(name, "sd1")) { 227 } else if (!strcmp(name, "sd1")) {
228 parent_name = "pll1_div2";
221 table = cpg_sd01_div_table; 229 table = cpg_sd01_div_table;
222 shift = 0; 230 shift = 0;
223 } else if (!strcmp(name, "z")) { 231 } else if (!strcmp(name, "z")) {
diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile
index 0303c0b99cd0..7e2d15a0c7b8 100644
--- a/drivers/clk/socfpga/Makefile
+++ b/drivers/clk/socfpga/Makefile
@@ -1 +1,4 @@
1obj-y += clk.o 1obj-y += clk.o
2obj-y += clk-gate.o
3obj-y += clk-pll.o
4obj-y += clk-periph.o
diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c
new file mode 100644
index 000000000000..501d513bf890
--- /dev/null
+++ b/drivers/clk/socfpga/clk-gate.c
@@ -0,0 +1,263 @@
1/*
2 * Copyright 2011-2012 Calxeda, Inc.
3 * Copyright (C) 2012-2013 Altera Corporation <www.altera.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * Based from clk-highbank.c
16 *
17 */
18#include <linux/clk.h>
19#include <linux/clkdev.h>
20#include <linux/clk-provider.h>
21#include <linux/io.h>
22#include <linux/mfd/syscon.h>
23#include <linux/of.h>
24#include <linux/regmap.h>
25
26#include "clk.h"
27
28#define SOCFPGA_L4_MP_CLK "l4_mp_clk"
29#define SOCFPGA_L4_SP_CLK "l4_sp_clk"
30#define SOCFPGA_NAND_CLK "nand_clk"
31#define SOCFPGA_NAND_X_CLK "nand_x_clk"
32#define SOCFPGA_MMC_CLK "sdmmc_clk"
33#define SOCFPGA_GPIO_DB_CLK_OFFSET 0xA8
34
35#define div_mask(width) ((1 << (width)) - 1)
36#define streq(a, b) (strcmp((a), (b)) == 0)
37
38#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw)
39
40/* SDMMC Group for System Manager defines */
41#define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108
42#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
43 ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
44
45static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
46{
47 u32 l4_src;
48 u32 perpll_src;
49
50 if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
51 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
52 return l4_src &= 0x1;
53 }
54 if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
55 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
56 return !!(l4_src & 2);
57 }
58
59 perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
60 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
61 return perpll_src &= 0x3;
62 if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
63 streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
64 return (perpll_src >> 2) & 3;
65
66 /* QSPI clock */
67 return (perpll_src >> 4) & 3;
68
69}
70
71static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
72{
73 u32 src_reg;
74
75 if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
76 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
77 src_reg &= ~0x1;
78 src_reg |= parent;
79 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
80 } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
81 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
82 src_reg &= ~0x2;
83 src_reg |= (parent << 1);
84 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
85 } else {
86 src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
87 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
88 src_reg &= ~0x3;
89 src_reg |= parent;
90 } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
91 streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
92 src_reg &= ~0xC;
93 src_reg |= (parent << 2);
94 } else {/* QSPI clock */
95 src_reg &= ~0x30;
96 src_reg |= (parent << 4);
97 }
98 writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
99 }
100
101 return 0;
102}
103
104static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
105 unsigned long parent_rate)
106{
107 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
108 u32 div = 1, val;
109
110 if (socfpgaclk->fixed_div)
111 div = socfpgaclk->fixed_div;
112 else if (socfpgaclk->div_reg) {
113 val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
114 val &= div_mask(socfpgaclk->width);
115 /* Check for GPIO_DB_CLK by its offset */
116 if ((int) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET)
117 div = val + 1;
118 else
119 div = (1 << val);
120 }
121
122 return parent_rate / div;
123}
124
125static int socfpga_clk_prepare(struct clk_hw *hwclk)
126{
127 struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
128 struct regmap *sys_mgr_base_addr;
129 int i;
130 u32 hs_timing;
131 u32 clk_phase[2];
132
133 if (socfpgaclk->clk_phase[0] || socfpgaclk->clk_phase[1]) {
134 sys_mgr_base_addr = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
135 if (IS_ERR(sys_mgr_base_addr)) {
136 pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__);
137 return -EINVAL;
138 }
139
140 for (i = 0; i < 2; i++) {
141 switch (socfpgaclk->clk_phase[i]) {
142 case 0:
143 clk_phase[i] = 0;
144 break;
145 case 45:
146 clk_phase[i] = 1;
147 break;
148 case 90:
149 clk_phase[i] = 2;
150 break;
151 case 135:
152 clk_phase[i] = 3;
153 break;
154 case 180:
155 clk_phase[i] = 4;
156 break;
157 case 225:
158 clk_phase[i] = 5;
159 break;
160 case 270:
161 clk_phase[i] = 6;
162 break;
163 case 315:
164 clk_phase[i] = 7;
165 break;
166 default:
167 clk_phase[i] = 0;
168 break;
169 }
170 }
171 hs_timing = SYSMGR_SDMMC_CTRL_SET(clk_phase[0], clk_phase[1]);
172 regmap_write(sys_mgr_base_addr, SYSMGR_SDMMCGRP_CTRL_OFFSET,
173 hs_timing);
174 }
175 return 0;
176}
177
178static struct clk_ops gateclk_ops = {
179 .prepare = socfpga_clk_prepare,
180 .recalc_rate = socfpga_clk_recalc_rate,
181 .get_parent = socfpga_clk_get_parent,
182 .set_parent = socfpga_clk_set_parent,
183};
184
185static void __init __socfpga_gate_init(struct device_node *node,
186 const struct clk_ops *ops)
187{
188 u32 clk_gate[2];
189 u32 div_reg[3];
190 u32 clk_phase[2];
191 u32 fixed_div;
192 struct clk *clk;
193 struct socfpga_gate_clk *socfpga_clk;
194 const char *clk_name = node->name;
195 const char *parent_name[SOCFPGA_MAX_PARENTS];
196 struct clk_init_data init;
197 int rc;
198 int i = 0;
199
200 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
201 if (WARN_ON(!socfpga_clk))
202 return;
203
204 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
205 if (rc)
206 clk_gate[0] = 0;
207
208 if (clk_gate[0]) {
209 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
210 socfpga_clk->hw.bit_idx = clk_gate[1];
211
212 gateclk_ops.enable = clk_gate_ops.enable;
213 gateclk_ops.disable = clk_gate_ops.disable;
214 }
215
216 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
217 if (rc)
218 socfpga_clk->fixed_div = 0;
219 else
220 socfpga_clk->fixed_div = fixed_div;
221
222 rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
223 if (!rc) {
224 socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0];
225 socfpga_clk->shift = div_reg[1];
226 socfpga_clk->width = div_reg[2];
227 } else {
228 socfpga_clk->div_reg = 0;
229 }
230
231 rc = of_property_read_u32_array(node, "clk-phase", clk_phase, 2);
232 if (!rc) {
233 socfpga_clk->clk_phase[0] = clk_phase[0];
234 socfpga_clk->clk_phase[1] = clk_phase[1];
235 }
236
237 of_property_read_string(node, "clock-output-names", &clk_name);
238
239 init.name = clk_name;
240 init.ops = ops;
241 init.flags = 0;
242 while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] =
243 of_clk_get_parent_name(node, i)) != NULL)
244 i++;
245
246 init.parent_names = parent_name;
247 init.num_parents = i;
248 socfpga_clk->hw.hw.init = &init;
249
250 clk = clk_register(NULL, &socfpga_clk->hw.hw);
251 if (WARN_ON(IS_ERR(clk))) {
252 kfree(socfpga_clk);
253 return;
254 }
255 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
256 if (WARN_ON(rc))
257 return;
258}
259
260void __init socfpga_gate_init(struct device_node *node)
261{
262 __socfpga_gate_init(node, &gateclk_ops);
263}
diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c
new file mode 100644
index 000000000000..81623a3736f9
--- /dev/null
+++ b/drivers/clk/socfpga/clk-periph.c
@@ -0,0 +1,94 @@
1/*
2 * Copyright 2011-2012 Calxeda, Inc.
3 * Copyright (C) 2012-2013 Altera Corporation <www.altera.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * Based from clk-highbank.c
16 *
17 */
18#include <linux/clk.h>
19#include <linux/clkdev.h>
20#include <linux/clk-provider.h>
21#include <linux/io.h>
22#include <linux/of.h>
23
24#include "clk.h"
25
26#define to_socfpga_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw.hw)
27
28static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
29 unsigned long parent_rate)
30{
31 struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk);
32 u32 div;
33
34 if (socfpgaclk->fixed_div)
35 div = socfpgaclk->fixed_div;
36 else
37 div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1);
38
39 return parent_rate / div;
40}
41
42static const struct clk_ops periclk_ops = {
43 .recalc_rate = clk_periclk_recalc_rate,
44};
45
46static __init void __socfpga_periph_init(struct device_node *node,
47 const struct clk_ops *ops)
48{
49 u32 reg;
50 struct clk *clk;
51 struct socfpga_periph_clk *periph_clk;
52 const char *clk_name = node->name;
53 const char *parent_name;
54 struct clk_init_data init;
55 int rc;
56 u32 fixed_div;
57
58 of_property_read_u32(node, "reg", &reg);
59
60 periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
61 if (WARN_ON(!periph_clk))
62 return;
63
64 periph_clk->hw.reg = clk_mgr_base_addr + reg;
65
66 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
67 if (rc)
68 periph_clk->fixed_div = 0;
69 else
70 periph_clk->fixed_div = fixed_div;
71
72 of_property_read_string(node, "clock-output-names", &clk_name);
73
74 init.name = clk_name;
75 init.ops = ops;
76 init.flags = 0;
77 parent_name = of_clk_get_parent_name(node, 0);
78 init.parent_names = &parent_name;
79 init.num_parents = 1;
80
81 periph_clk->hw.hw.init = &init;
82
83 clk = clk_register(NULL, &periph_clk->hw.hw);
84 if (WARN_ON(IS_ERR(clk))) {
85 kfree(periph_clk);
86 return;
87 }
88 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
89}
90
91void __init socfpga_periph_init(struct device_node *node)
92{
93 __socfpga_periph_init(node, &periclk_ops);
94}
diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c
new file mode 100644
index 000000000000..88dafb5e9627
--- /dev/null
+++ b/drivers/clk/socfpga/clk-pll.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright 2011-2012 Calxeda, Inc.
3 * Copyright (C) 2012-2013 Altera Corporation <www.altera.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * Based from clk-highbank.c
16 *
17 */
18#include <linux/clk.h>
19#include <linux/clkdev.h>
20#include <linux/clk-provider.h>
21#include <linux/io.h>
22#include <linux/of.h>
23
24#include "clk.h"
25
26/* Clock bypass bits */
27#define MAINPLL_BYPASS (1<<0)
28#define SDRAMPLL_BYPASS (1<<1)
29#define SDRAMPLL_SRC_BYPASS (1<<2)
30#define PERPLL_BYPASS (1<<3)
31#define PERPLL_SRC_BYPASS (1<<4)
32
33#define SOCFPGA_PLL_BG_PWRDWN 0
34#define SOCFPGA_PLL_EXT_ENA 1
35#define SOCFPGA_PLL_PWR_DOWN 2
36#define SOCFPGA_PLL_DIVF_MASK 0x0000FFF8
37#define SOCFPGA_PLL_DIVF_SHIFT 3
38#define SOCFPGA_PLL_DIVQ_MASK 0x003F0000
39#define SOCFPGA_PLL_DIVQ_SHIFT 16
40
41#define CLK_MGR_PLL_CLK_SRC_SHIFT 22
42#define CLK_MGR_PLL_CLK_SRC_MASK 0x3
43
44#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw)
45
46static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
47 unsigned long parent_rate)
48{
49 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
50 unsigned long divf, divq, reg;
51 unsigned long long vco_freq;
52 unsigned long bypass;
53
54 reg = readl(socfpgaclk->hw.reg);
55 bypass = readl(clk_mgr_base_addr + CLKMGR_BYPASS);
56 if (bypass & MAINPLL_BYPASS)
57 return parent_rate;
58
59 divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
60 divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
61 vco_freq = (unsigned long long)parent_rate * (divf + 1);
62 do_div(vco_freq, (1 + divq));
63 return (unsigned long)vco_freq;
64}
65
66static u8 clk_pll_get_parent(struct clk_hw *hwclk)
67{
68 u32 pll_src;
69 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
70
71 pll_src = readl(socfpgaclk->hw.reg);
72 return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) &
73 CLK_MGR_PLL_CLK_SRC_MASK;
74}
75
76static struct clk_ops clk_pll_ops = {
77 .recalc_rate = clk_pll_recalc_rate,
78 .get_parent = clk_pll_get_parent,
79};
80
81static __init struct clk *__socfpga_pll_init(struct device_node *node,
82 const struct clk_ops *ops)
83{
84 u32 reg;
85 struct clk *clk;
86 struct socfpga_pll *pll_clk;
87 const char *clk_name = node->name;
88 const char *parent_name[SOCFPGA_MAX_PARENTS];
89 struct clk_init_data init;
90 int rc;
91 int i = 0;
92
93 of_property_read_u32(node, "reg", &reg);
94
95 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
96 if (WARN_ON(!pll_clk))
97 return NULL;
98
99 pll_clk->hw.reg = clk_mgr_base_addr + reg;
100
101 of_property_read_string(node, "clock-output-names", &clk_name);
102
103 init.name = clk_name;
104 init.ops = ops;
105 init.flags = 0;
106
107 while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] =
108 of_clk_get_parent_name(node, i)) != NULL)
109 i++;
110
111 init.num_parents = i;
112 init.parent_names = parent_name;
113 pll_clk->hw.hw.init = &init;
114
115 pll_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
116 clk_pll_ops.enable = clk_gate_ops.enable;
117 clk_pll_ops.disable = clk_gate_ops.disable;
118
119 clk = clk_register(NULL, &pll_clk->hw.hw);
120 if (WARN_ON(IS_ERR(clk))) {
121 kfree(pll_clk);
122 return NULL;
123 }
124 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
125 return clk;
126}
127
128void __init socfpga_pll_init(struct device_node *node)
129{
130 __socfpga_pll_init(node, &clk_pll_ops);
131}
diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c
index 5983a26a8c5f..6217d5dc6644 100644
--- a/drivers/clk/socfpga/clk.c
+++ b/drivers/clk/socfpga/clk.c
@@ -22,325 +22,23 @@
22#include <linux/clk-provider.h> 22#include <linux/clk-provider.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_address.h>
25 26
26/* Clock Manager offsets */ 27#include "clk.h"
27#define CLKMGR_CTRL 0x0
28#define CLKMGR_BYPASS 0x4
29#define CLKMGR_L4SRC 0x70
30#define CLKMGR_PERPLL_SRC 0xAC
31 28
32/* Clock bypass bits */ 29void __iomem *clk_mgr_base_addr;
33#define MAINPLL_BYPASS (1<<0)
34#define SDRAMPLL_BYPASS (1<<1)
35#define SDRAMPLL_SRC_BYPASS (1<<2)
36#define PERPLL_BYPASS (1<<3)
37#define PERPLL_SRC_BYPASS (1<<4)
38 30
39#define SOCFPGA_PLL_BG_PWRDWN 0 31static struct of_device_id socfpga_child_clocks[] = {
40#define SOCFPGA_PLL_EXT_ENA 1 32 { .compatible = "altr,socfpga-pll-clock", socfpga_pll_init, },
41#define SOCFPGA_PLL_PWR_DOWN 2 33 { .compatible = "altr,socfpga-perip-clk", socfpga_periph_init, },
42#define SOCFPGA_PLL_DIVF_MASK 0x0000FFF8 34 { .compatible = "altr,socfpga-gate-clk", socfpga_gate_init, },
43#define SOCFPGA_PLL_DIVF_SHIFT 3 35 {},
44#define SOCFPGA_PLL_DIVQ_MASK 0x003F0000
45#define SOCFPGA_PLL_DIVQ_SHIFT 16
46#define SOCFGPA_MAX_PARENTS 3
47
48#define SOCFPGA_L4_MP_CLK "l4_mp_clk"
49#define SOCFPGA_L4_SP_CLK "l4_sp_clk"
50#define SOCFPGA_NAND_CLK "nand_clk"
51#define SOCFPGA_NAND_X_CLK "nand_x_clk"
52#define SOCFPGA_MMC_CLK "sdmmc_clk"
53#define SOCFPGA_DB_CLK "gpio_db_clk"
54
55#define div_mask(width) ((1 << (width)) - 1)
56#define streq(a, b) (strcmp((a), (b)) == 0)
57
58extern void __iomem *clk_mgr_base_addr;
59
60struct socfpga_clk {
61 struct clk_gate hw;
62 char *parent_name;
63 char *clk_name;
64 u32 fixed_div;
65 void __iomem *div_reg;
66 u32 width; /* only valid if div_reg != 0 */
67 u32 shift; /* only valid if div_reg != 0 */
68};
69#define to_socfpga_clk(p) container_of(p, struct socfpga_clk, hw.hw)
70
71static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
72 unsigned long parent_rate)
73{
74 struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
75 unsigned long divf, divq, vco_freq, reg;
76 unsigned long bypass;
77
78 reg = readl(socfpgaclk->hw.reg);
79 bypass = readl(clk_mgr_base_addr + CLKMGR_BYPASS);
80 if (bypass & MAINPLL_BYPASS)
81 return parent_rate;
82
83 divf = (reg & SOCFPGA_PLL_DIVF_MASK) >> SOCFPGA_PLL_DIVF_SHIFT;
84 divq = (reg & SOCFPGA_PLL_DIVQ_MASK) >> SOCFPGA_PLL_DIVQ_SHIFT;
85 vco_freq = parent_rate * (divf + 1);
86 return vco_freq / (1 + divq);
87}
88
89
90static struct clk_ops clk_pll_ops = {
91 .recalc_rate = clk_pll_recalc_rate,
92};
93
94static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk,
95 unsigned long parent_rate)
96{
97 struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
98 u32 div;
99
100 if (socfpgaclk->fixed_div)
101 div = socfpgaclk->fixed_div;
102 else
103 div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1);
104
105 return parent_rate / div;
106}
107
108static const struct clk_ops periclk_ops = {
109 .recalc_rate = clk_periclk_recalc_rate,
110};
111
112static __init struct clk *socfpga_clk_init(struct device_node *node,
113 const struct clk_ops *ops)
114{
115 u32 reg;
116 struct clk *clk;
117 struct socfpga_clk *socfpga_clk;
118 const char *clk_name = node->name;
119 const char *parent_name;
120 struct clk_init_data init;
121 int rc;
122 u32 fixed_div;
123
124 of_property_read_u32(node, "reg", &reg);
125
126 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
127 if (WARN_ON(!socfpga_clk))
128 return NULL;
129
130 socfpga_clk->hw.reg = clk_mgr_base_addr + reg;
131
132 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
133 if (rc)
134 socfpga_clk->fixed_div = 0;
135 else
136 socfpga_clk->fixed_div = fixed_div;
137
138 of_property_read_string(node, "clock-output-names", &clk_name);
139
140 init.name = clk_name;
141 init.ops = ops;
142 init.flags = 0;
143 parent_name = of_clk_get_parent_name(node, 0);
144 init.parent_names = &parent_name;
145 init.num_parents = 1;
146
147 socfpga_clk->hw.hw.init = &init;
148
149 if (streq(clk_name, "main_pll") ||
150 streq(clk_name, "periph_pll") ||
151 streq(clk_name, "sdram_pll")) {
152 socfpga_clk->hw.bit_idx = SOCFPGA_PLL_EXT_ENA;
153 clk_pll_ops.enable = clk_gate_ops.enable;
154 clk_pll_ops.disable = clk_gate_ops.disable;
155 }
156
157 clk = clk_register(NULL, &socfpga_clk->hw.hw);
158 if (WARN_ON(IS_ERR(clk))) {
159 kfree(socfpga_clk);
160 return NULL;
161 }
162 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
163 return clk;
164}
165
166static u8 socfpga_clk_get_parent(struct clk_hw *hwclk)
167{
168 u32 l4_src;
169 u32 perpll_src;
170
171 if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
172 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
173 return l4_src &= 0x1;
174 }
175 if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
176 l4_src = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
177 return !!(l4_src & 2);
178 }
179
180 perpll_src = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
181 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK))
182 return perpll_src &= 0x3;
183 if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
184 streq(hwclk->init->name, SOCFPGA_NAND_X_CLK))
185 return (perpll_src >> 2) & 3;
186
187 /* QSPI clock */
188 return (perpll_src >> 4) & 3;
189
190}
191
192static int socfpga_clk_set_parent(struct clk_hw *hwclk, u8 parent)
193{
194 u32 src_reg;
195
196 if (streq(hwclk->init->name, SOCFPGA_L4_MP_CLK)) {
197 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
198 src_reg &= ~0x1;
199 src_reg |= parent;
200 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
201 } else if (streq(hwclk->init->name, SOCFPGA_L4_SP_CLK)) {
202 src_reg = readl(clk_mgr_base_addr + CLKMGR_L4SRC);
203 src_reg &= ~0x2;
204 src_reg |= (parent << 1);
205 writel(src_reg, clk_mgr_base_addr + CLKMGR_L4SRC);
206 } else {
207 src_reg = readl(clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
208 if (streq(hwclk->init->name, SOCFPGA_MMC_CLK)) {
209 src_reg &= ~0x3;
210 src_reg |= parent;
211 } else if (streq(hwclk->init->name, SOCFPGA_NAND_CLK) ||
212 streq(hwclk->init->name, SOCFPGA_NAND_X_CLK)) {
213 src_reg &= ~0xC;
214 src_reg |= (parent << 2);
215 } else {/* QSPI clock */
216 src_reg &= ~0x30;
217 src_reg |= (parent << 4);
218 }
219 writel(src_reg, clk_mgr_base_addr + CLKMGR_PERPLL_SRC);
220 }
221
222 return 0;
223}
224
225static unsigned long socfpga_clk_recalc_rate(struct clk_hw *hwclk,
226 unsigned long parent_rate)
227{
228 struct socfpga_clk *socfpgaclk = to_socfpga_clk(hwclk);
229 u32 div = 1, val;
230
231 if (socfpgaclk->fixed_div)
232 div = socfpgaclk->fixed_div;
233 else if (socfpgaclk->div_reg) {
234 val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
235 val &= div_mask(socfpgaclk->width);
236 if (streq(hwclk->init->name, SOCFPGA_DB_CLK))
237 div = val + 1;
238 else
239 div = (1 << val);
240 }
241
242 return parent_rate / div;
243}
244
245static struct clk_ops gateclk_ops = {
246 .recalc_rate = socfpga_clk_recalc_rate,
247 .get_parent = socfpga_clk_get_parent,
248 .set_parent = socfpga_clk_set_parent,
249}; 36};
250 37
251static void __init socfpga_gate_clk_init(struct device_node *node, 38static void __init socfpga_clkmgr_init(struct device_node *node)
252 const struct clk_ops *ops)
253{
254 u32 clk_gate[2];
255 u32 div_reg[3];
256 u32 fixed_div;
257 struct clk *clk;
258 struct socfpga_clk *socfpga_clk;
259 const char *clk_name = node->name;
260 const char *parent_name[SOCFGPA_MAX_PARENTS];
261 struct clk_init_data init;
262 int rc;
263 int i = 0;
264
265 socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
266 if (WARN_ON(!socfpga_clk))
267 return;
268
269 rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2);
270 if (rc)
271 clk_gate[0] = 0;
272
273 if (clk_gate[0]) {
274 socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
275 socfpga_clk->hw.bit_idx = clk_gate[1];
276
277 gateclk_ops.enable = clk_gate_ops.enable;
278 gateclk_ops.disable = clk_gate_ops.disable;
279 }
280
281 rc = of_property_read_u32(node, "fixed-divider", &fixed_div);
282 if (rc)
283 socfpga_clk->fixed_div = 0;
284 else
285 socfpga_clk->fixed_div = fixed_div;
286
287 rc = of_property_read_u32_array(node, "div-reg", div_reg, 3);
288 if (!rc) {
289 socfpga_clk->div_reg = clk_mgr_base_addr + div_reg[0];
290 socfpga_clk->shift = div_reg[1];
291 socfpga_clk->width = div_reg[2];
292 } else {
293 socfpga_clk->div_reg = NULL;
294 }
295
296 of_property_read_string(node, "clock-output-names", &clk_name);
297
298 init.name = clk_name;
299 init.ops = ops;
300 init.flags = 0;
301 while (i < SOCFGPA_MAX_PARENTS && (parent_name[i] =
302 of_clk_get_parent_name(node, i)) != NULL)
303 i++;
304
305 init.parent_names = parent_name;
306 init.num_parents = i;
307 socfpga_clk->hw.hw.init = &init;
308
309 clk = clk_register(NULL, &socfpga_clk->hw.hw);
310 if (WARN_ON(IS_ERR(clk))) {
311 kfree(socfpga_clk);
312 return;
313 }
314 rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
315 if (WARN_ON(rc))
316 return;
317}
318
319static void __init socfpga_pll_init(struct device_node *node)
320{ 39{
321 socfpga_clk_init(node, &clk_pll_ops); 40 clk_mgr_base_addr = of_iomap(node, 0);
41 of_clk_init(socfpga_child_clocks);
322} 42}
323CLK_OF_DECLARE(socfpga_pll, "altr,socfpga-pll-clock", socfpga_pll_init); 43CLK_OF_DECLARE(socfpga_mgr, "altr,clk-mgr", socfpga_clkmgr_init);
324 44
325static void __init socfpga_periph_init(struct device_node *node)
326{
327 socfpga_clk_init(node, &periclk_ops);
328}
329CLK_OF_DECLARE(socfpga_periph, "altr,socfpga-perip-clk", socfpga_periph_init);
330
331static void __init socfpga_gate_init(struct device_node *node)
332{
333 socfpga_gate_clk_init(node, &gateclk_ops);
334}
335CLK_OF_DECLARE(socfpga_gate, "altr,socfpga-gate-clk", socfpga_gate_init);
336
337void __init socfpga_init_clocks(void)
338{
339 struct clk *clk;
340 int ret;
341
342 clk = clk_register_fixed_factor(NULL, "smp_twd", "mpuclk", 0, 1, 4);
343 ret = clk_register_clkdev(clk, NULL, "smp_twd");
344 if (ret)
345 pr_err("smp_twd alias not registered\n");
346}
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
new file mode 100644
index 000000000000..d2e54019c94f
--- /dev/null
+++ b/drivers/clk/socfpga/clk.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2013, Steffen Trumtrar <s.trumtrar@pengutronix.de>
3 *
4 * based on drivers/clk/tegra/clk.h
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 */
16
17#ifndef __SOCFPGA_CLK_H
18#define __SOCFPGA_CLK_H
19
20#include <linux/clk-provider.h>
21#include <linux/clkdev.h>
22
23/* Clock Manager offsets */
24#define CLKMGR_CTRL 0x0
25#define CLKMGR_BYPASS 0x4
26#define CLKMGR_L4SRC 0x70
27#define CLKMGR_PERPLL_SRC 0xAC
28
29#define SOCFPGA_MAX_PARENTS 3
30
31extern void __iomem *clk_mgr_base_addr;
32
33void __init socfpga_pll_init(struct device_node *node);
34void __init socfpga_periph_init(struct device_node *node);
35void __init socfpga_gate_init(struct device_node *node);
36
37struct socfpga_pll {
38 struct clk_gate hw;
39};
40
41struct socfpga_gate_clk {
42 struct clk_gate hw;
43 char *parent_name;
44 u32 fixed_div;
45 void __iomem *div_reg;
46 u32 width; /* only valid if div_reg != 0 */
47 u32 shift; /* only valid if div_reg != 0 */
48 u32 clk_phase[2];
49};
50
51struct socfpga_periph_clk {
52 struct clk_gate hw;
53 char *parent_name;
54 u32 fixed_div;
55};
56
57#endif /* SOCFPGA_CLK_H */
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index 4d75b1f37e3a..290f9c1a3749 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -59,7 +59,7 @@ static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
59 return 0; 59 return 0;
60 60
61 if (divider_ux1 > get_max_div(divider)) 61 if (divider_ux1 > get_max_div(divider))
62 return -EINVAL; 62 return get_max_div(divider);
63 63
64 return divider_ux1; 64 return divider_ux1;
65} 65}
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h
index cf0c323f2c36..c39613c519af 100644
--- a/drivers/clk/tegra/clk-id.h
+++ b/drivers/clk/tegra/clk-id.h
@@ -180,9 +180,13 @@ enum clk_id {
180 tegra_clk_sbc6_8, 180 tegra_clk_sbc6_8,
181 tegra_clk_sclk, 181 tegra_clk_sclk,
182 tegra_clk_sdmmc1, 182 tegra_clk_sdmmc1,
183 tegra_clk_sdmmc1_8,
183 tegra_clk_sdmmc2, 184 tegra_clk_sdmmc2,
185 tegra_clk_sdmmc2_8,
184 tegra_clk_sdmmc3, 186 tegra_clk_sdmmc3,
187 tegra_clk_sdmmc3_8,
185 tegra_clk_sdmmc4, 188 tegra_clk_sdmmc4,
189 tegra_clk_sdmmc4_8,
186 tegra_clk_se, 190 tegra_clk_se,
187 tegra_clk_soc_therm, 191 tegra_clk_soc_therm,
188 tegra_clk_sor0, 192 tegra_clk_sor0,
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 356e9b804421..9e899c18af86 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -130,7 +130,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
130 .disable = clk_periph_disable, 130 .disable = clk_periph_disable,
131}; 131};
132 132
133const struct clk_ops tegra_clk_periph_no_gate_ops = { 133static const struct clk_ops tegra_clk_periph_no_gate_ops = {
134 .get_parent = clk_periph_get_parent, 134 .get_parent = clk_periph_get_parent,
135 .set_parent = clk_periph_set_parent, 135 .set_parent = clk_periph_set_parent,
136 .recalc_rate = clk_periph_recalc_rate, 136 .recalc_rate = clk_periph_recalc_rate,
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c
index 5c35885f4a7c..1fa5c3f33b20 100644
--- a/drivers/clk/tegra/clk-tegra-periph.c
+++ b/drivers/clk/tegra/clk-tegra-periph.c
@@ -371,9 +371,7 @@ static const char *mux_pllp3_pllc_clkm[] = {
371static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = { 371static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = {
372 "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m" 372 "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m"
373}; 373};
374static u32 mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx[] = { 374#define mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx NULL
375 [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
376};
377 375
378static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = { 376static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = {
379 "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4", 377 "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4",
@@ -465,6 +463,10 @@ static struct tegra_periph_init_data periph_clks[] = {
465 MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), 463 MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1),
466 MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), 464 MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1),
467 MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), 465 MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2),
466 MUX8("sdmmc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1_8),
467 MUX8("sdmmc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2_8),
468 MUX8("sdmmc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3_8),
469 MUX8("sdmmc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4_8),
468 MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), 470 MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8),
469 MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), 471 MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8),
470 MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), 472 MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8),
@@ -492,7 +494,7 @@ static struct tegra_periph_init_data periph_clks[] = {
492 UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), 494 UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb),
493 UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), 495 UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc),
494 UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), 496 UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd),
495 UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 65, tegra_clk_uarte), 497 UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 66, tegra_clk_uarte),
496 XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), 498 XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src),
497 XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), 499 XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src),
498 XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), 500 XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src),
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index 05dce4aa2c11..feb3201c85ce 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -120,7 +120,7 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base,
120 ARRAY_SIZE(cclk_lp_parents), 120 ARRAY_SIZE(cclk_lp_parents),
121 CLK_SET_RATE_PARENT, 121 CLK_SET_RATE_PARENT,
122 clk_base + CCLKLP_BURST_POLICY, 122 clk_base + CCLKLP_BURST_POLICY,
123 0, 4, 8, 9, NULL); 123 TEGRA_DIVIDER_2, 4, 8, 9, NULL);
124 *dt_clk = clk; 124 *dt_clk = clk;
125 } 125 }
126 126
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 90d9d25f2228..80431f0fb268 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -682,12 +682,12 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
682 [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true }, 682 [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true },
683 [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true }, 683 [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true },
684 [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true }, 684 [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true },
685 [tegra_clk_sdmmc2] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true }, 685 [tegra_clk_sdmmc2_8] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true },
686 [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true }, 686 [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true },
687 [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true }, 687 [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true },
688 [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true }, 688 [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true },
689 [tegra_clk_sdmmc1] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true }, 689 [tegra_clk_sdmmc1_8] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true },
690 [tegra_clk_sdmmc4] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true }, 690 [tegra_clk_sdmmc4_8] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true },
691 [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true }, 691 [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true },
692 [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true }, 692 [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true },
693 [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true }, 693 [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true },
@@ -723,7 +723,7 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = {
723 [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true }, 723 [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true },
724 [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true }, 724 [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true },
725 [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true }, 725 [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true },
726 [tegra_clk_sdmmc3] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true }, 726 [tegra_clk_sdmmc3_8] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true },
727 [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true }, 727 [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true },
728 [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true }, 728 [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true },
729 [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true }, 729 [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true },
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index aff86b5bc745..166e02f16c8a 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -516,11 +516,11 @@ static struct div_nmp pllp_nmp = {
516}; 516};
517 517
518static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { 518static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
519 {12000000, 216000000, 432, 12, 1, 8}, 519 {12000000, 408000000, 408, 12, 0, 8},
520 {13000000, 216000000, 432, 13, 1, 8}, 520 {13000000, 408000000, 408, 13, 0, 8},
521 {16800000, 216000000, 360, 14, 1, 8}, 521 {16800000, 408000000, 340, 14, 0, 8},
522 {19200000, 216000000, 360, 16, 1, 8}, 522 {19200000, 408000000, 340, 16, 0, 8},
523 {26000000, 216000000, 432, 26, 1, 8}, 523 {26000000, 408000000, 408, 26, 0, 8},
524 {0, 0, 0, 0, 0, 0}, 524 {0, 0, 0, 0, 0, 0},
525}; 525};
526 526
@@ -570,6 +570,15 @@ static struct tegra_clk_pll_params pll_a_params = {
570 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, 570 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK,
571}; 571};
572 572
573static struct div_nmp plld_nmp = {
574 .divm_shift = 0,
575 .divm_width = 5,
576 .divn_shift = 8,
577 .divn_width = 11,
578 .divp_shift = 20,
579 .divp_width = 3,
580};
581
573static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { 582static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
574 {12000000, 216000000, 864, 12, 4, 12}, 583 {12000000, 216000000, 864, 12, 4, 12},
575 {13000000, 216000000, 864, 13, 4, 12}, 584 {13000000, 216000000, 864, 13, 4, 12},
@@ -603,19 +612,18 @@ static struct tegra_clk_pll_params pll_d_params = {
603 .lock_mask = PLL_BASE_LOCK, 612 .lock_mask = PLL_BASE_LOCK,
604 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, 613 .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
605 .lock_delay = 1000, 614 .lock_delay = 1000,
606 .div_nmp = &pllp_nmp, 615 .div_nmp = &plld_nmp,
607 .freq_table = pll_d_freq_table, 616 .freq_table = pll_d_freq_table,
608 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | 617 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
609 TEGRA_PLL_USE_LOCK, 618 TEGRA_PLL_USE_LOCK,
610}; 619};
611 620
612static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { 621static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = {
613 { 12000000, 148500000, 99, 1, 8}, 622 { 12000000, 594000000, 99, 1, 2},
614 { 12000000, 594000000, 99, 1, 1}, 623 { 13000000, 594000000, 91, 1, 2}, /* actual: 591.5 MHz */
615 { 13000000, 594000000, 91, 1, 1}, /* actual: 591.5 MHz */ 624 { 16800000, 594000000, 71, 1, 2}, /* actual: 596.4 MHz */
616 { 16800000, 594000000, 71, 1, 1}, /* actual: 596.4 MHz */ 625 { 19200000, 594000000, 62, 1, 2}, /* actual: 595.2 MHz */
617 { 19200000, 594000000, 62, 1, 1}, /* actual: 595.2 MHz */ 626 { 26000000, 594000000, 91, 2, 2}, /* actual: 591.5 MHz */
618 { 26000000, 594000000, 91, 2, 1}, /* actual: 591.5 MHz */
619 { 0, 0, 0, 0, 0, 0 }, 627 { 0, 0, 0, 0, 0, 0 },
620}; 628};
621 629
@@ -753,21 +761,19 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
753 [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true }, 761 [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true },
754 [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true }, 762 [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true },
755 [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true }, 763 [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true },
756 [tegra_clk_sdmmc2] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, 764 [tegra_clk_sdmmc2_8] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true },
757 [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, 765 [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true },
758 [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, 766 [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true },
759 [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, 767 [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true },
760 [tegra_clk_sdmmc1] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, 768 [tegra_clk_sdmmc1_8] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true },
761 [tegra_clk_sdmmc4] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, 769 [tegra_clk_sdmmc4_8] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true },
762 [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, 770 [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true },
763 [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true }, 771 [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true },
764 [tegra_clk_gr2d] = { .dt_id = TEGRA124_CLK_GR_2D, .present = true },
765 [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true }, 772 [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true },
766 [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true }, 773 [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true },
767 [tegra_clk_gr3d] = { .dt_id = TEGRA124_CLK_GR_3D, .present = true },
768 [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true }, 774 [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true },
769 [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true }, 775 [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true },
770 [tegra_clk_host1x] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true }, 776 [tegra_clk_host1x_8] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true },
771 [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true }, 777 [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true },
772 [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true }, 778 [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true },
773 [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true }, 779 [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true },
@@ -794,7 +800,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
794 [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true }, 800 [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true },
795 [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true }, 801 [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true },
796 [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true }, 802 [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true },
797 [tegra_clk_sdmmc3] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true }, 803 [tegra_clk_sdmmc3_8] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true },
798 [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true }, 804 [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true },
799 [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true }, 805 [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true },
800 [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true }, 806 [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true },
@@ -1286,9 +1292,9 @@ static void __init tegra124_pll_init(void __iomem *clk_base,
1286 clk_register_clkdev(clk, "pll_d2", NULL); 1292 clk_register_clkdev(clk, "pll_d2", NULL);
1287 clks[TEGRA124_CLK_PLL_D2] = clk; 1293 clks[TEGRA124_CLK_PLL_D2] = clk;
1288 1294
1289 /* PLLD2_OUT0 ?? */ 1295 /* PLLD2_OUT0 */
1290 clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", 1296 clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2",
1291 CLK_SET_RATE_PARENT, 1, 2); 1297 CLK_SET_RATE_PARENT, 1, 1);
1292 clk_register_clkdev(clk, "pll_d2_out0", NULL); 1298 clk_register_clkdev(clk, "pll_d2_out0", NULL);
1293 clks[TEGRA124_CLK_PLL_D2_OUT0] = clk; 1299 clks[TEGRA124_CLK_PLL_D2_OUT0] = clk;
1294 1300
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index dbace152b2fa..dace2b1b5ae6 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -574,6 +574,8 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = {
574 [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true }, 574 [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true },
575 [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true }, 575 [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true },
576 [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, 576 [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true },
577 [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true },
578 [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true },
577}; 579};
578 580
579static unsigned long tegra20_clk_measure_input_freq(void) 581static unsigned long tegra20_clk_measure_input_freq(void)
diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c
index 776ee4594bd4..028b33783d38 100644
--- a/drivers/clk/ti/clk-33xx.c
+++ b/drivers/clk/ti/clk-33xx.c
@@ -34,7 +34,6 @@ static struct ti_dt_clk am33xx_clks[] = {
34 DT_CLK(NULL, "dpll_core_m5_ck", "dpll_core_m5_ck"), 34 DT_CLK(NULL, "dpll_core_m5_ck", "dpll_core_m5_ck"),
35 DT_CLK(NULL, "dpll_core_m6_ck", "dpll_core_m6_ck"), 35 DT_CLK(NULL, "dpll_core_m6_ck", "dpll_core_m6_ck"),
36 DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"), 36 DT_CLK(NULL, "dpll_mpu_ck", "dpll_mpu_ck"),
37 DT_CLK("cpu0", NULL, "dpll_mpu_ck"),
38 DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"), 37 DT_CLK(NULL, "dpll_mpu_m2_ck", "dpll_mpu_m2_ck"),
39 DT_CLK(NULL, "dpll_ddr_ck", "dpll_ddr_ck"), 38 DT_CLK(NULL, "dpll_ddr_ck", "dpll_ddr_ck"),
40 DT_CLK(NULL, "dpll_ddr_m2_ck", "dpll_ddr_m2_ck"), 39 DT_CLK(NULL, "dpll_ddr_m2_ck", "dpll_ddr_m2_ck"),
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index a15e445570b2..e6aa10db7bba 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -112,7 +112,7 @@ static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
112 return parent_rate; 112 return parent_rate;
113 } 113 }
114 114
115 return parent_rate / div; 115 return DIV_ROUND_UP(parent_rate, div);
116} 116}
117 117
118/* 118/*
@@ -182,7 +182,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
182 } 182 }
183 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 183 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
184 MULT_ROUND_UP(rate, i)); 184 MULT_ROUND_UP(rate, i));
185 now = parent_rate / i; 185 now = DIV_ROUND_UP(parent_rate, i);
186 if (now <= rate && now > best) { 186 if (now <= rate && now > best) {
187 bestdiv = i; 187 bestdiv = i;
188 best = now; 188 best = now;
@@ -205,7 +205,7 @@ static long ti_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
205 int div; 205 int div;
206 div = ti_clk_divider_bestdiv(hw, rate, prate); 206 div = ti_clk_divider_bestdiv(hw, rate, prate);
207 207
208 return *prate / div; 208 return DIV_ROUND_UP(*prate, div);
209} 209}
210 210
211static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, 211static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -216,7 +216,7 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
216 unsigned long flags = 0; 216 unsigned long flags = 0;
217 u32 val; 217 u32 val;
218 218
219 div = parent_rate / rate; 219 div = DIV_ROUND_UP(parent_rate, rate);
220 value = _get_val(divider, div); 220 value = _get_val(divider, div);
221 221
222 if (value > div_mask(divider)) 222 if (value > div_mask(divider))
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c
index cdeff299de26..7b55ef89baa5 100644
--- a/drivers/clk/ux500/u8500_of_clk.c
+++ b/drivers/clk/ux500/u8500_of_clk.c
@@ -29,7 +29,8 @@ static struct clk *prcc_kclk[(PRCC_NUM_PERIPH_CLUSTERS + 1) * PRCC_PERIPHS_PER_C
29#define PRCC_KCLK_STORE(clk, base, bit) \ 29#define PRCC_KCLK_STORE(clk, base, bit) \
30 prcc_kclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk 30 prcc_kclk[(base * PRCC_PERIPHS_PER_CLUSTER) + bit] = clk
31 31
32struct clk *ux500_twocell_get(struct of_phandle_args *clkspec, void *data) 32static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec,
33 void *data)
33{ 34{
34 struct clk **clk_data = data; 35 struct clk **clk_data = data;
35 unsigned int base, bit; 36 unsigned int base, bit;
diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c
index 09dd0173ea0a..e726c1b11218 100644
--- a/drivers/clk/zynq/clkc.c
+++ b/drivers/clk/zynq/clkc.c
@@ -148,7 +148,7 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
148 clks[fclk] = clk_register_gate(NULL, clk_name, 148 clks[fclk] = clk_register_gate(NULL, clk_name,
149 div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg, 149 div1_name, CLK_SET_RATE_PARENT, fclk_gate_reg,
150 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock); 150 0, CLK_GATE_SET_TO_DISABLE, fclk_gate_lock);
151 enable_reg = readl(fclk_gate_reg) & 1; 151 enable_reg = clk_readl(fclk_gate_reg) & 1;
152 if (enable && !enable_reg) { 152 if (enable && !enable_reg) {
153 if (clk_prepare_enable(clks[fclk])) 153 if (clk_prepare_enable(clks[fclk]))
154 pr_warn("%s: FCLK%u enable failed\n", __func__, 154 pr_warn("%s: FCLK%u enable failed\n", __func__,
@@ -277,7 +277,7 @@ static void __init zynq_clk_setup(struct device_node *np)
277 SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock); 277 SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock);
278 278
279 /* CPU clocks */ 279 /* CPU clocks */
280 tmp = readl(SLCR_621_TRUE) & 1; 280 tmp = clk_readl(SLCR_621_TRUE) & 1;
281 clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 281 clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4,
282 CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0, 282 CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0,
283 &armclk_lock); 283 &armclk_lock);
diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c
index 3226f54fa595..cec97596fe65 100644
--- a/drivers/clk/zynq/pll.c
+++ b/drivers/clk/zynq/pll.c
@@ -90,7 +90,7 @@ static unsigned long zynq_pll_recalc_rate(struct clk_hw *hw,
90 * makes probably sense to redundantly save fbdiv in the struct 90 * makes probably sense to redundantly save fbdiv in the struct
91 * zynq_pll to save the IO access. 91 * zynq_pll to save the IO access.
92 */ 92 */
93 fbdiv = (readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >> 93 fbdiv = (clk_readl(clk->pll_ctrl) & PLLCTRL_FBDIV_MASK) >>
94 PLLCTRL_FBDIV_SHIFT; 94 PLLCTRL_FBDIV_SHIFT;
95 95
96 return parent_rate * fbdiv; 96 return parent_rate * fbdiv;
@@ -112,7 +112,7 @@ static int zynq_pll_is_enabled(struct clk_hw *hw)
112 112
113 spin_lock_irqsave(clk->lock, flags); 113 spin_lock_irqsave(clk->lock, flags);
114 114
115 reg = readl(clk->pll_ctrl); 115 reg = clk_readl(clk->pll_ctrl);
116 116
117 spin_unlock_irqrestore(clk->lock, flags); 117 spin_unlock_irqrestore(clk->lock, flags);
118 118
@@ -138,10 +138,10 @@ static int zynq_pll_enable(struct clk_hw *hw)
138 /* Power up PLL and wait for lock */ 138 /* Power up PLL and wait for lock */
139 spin_lock_irqsave(clk->lock, flags); 139 spin_lock_irqsave(clk->lock, flags);
140 140
141 reg = readl(clk->pll_ctrl); 141 reg = clk_readl(clk->pll_ctrl);
142 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK); 142 reg &= ~(PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK);
143 writel(reg, clk->pll_ctrl); 143 clk_writel(reg, clk->pll_ctrl);
144 while (!(readl(clk->pll_status) & (1 << clk->lockbit))) 144 while (!(clk_readl(clk->pll_status) & (1 << clk->lockbit)))
145 ; 145 ;
146 146
147 spin_unlock_irqrestore(clk->lock, flags); 147 spin_unlock_irqrestore(clk->lock, flags);
@@ -168,9 +168,9 @@ static void zynq_pll_disable(struct clk_hw *hw)
168 /* shut down PLL */ 168 /* shut down PLL */
169 spin_lock_irqsave(clk->lock, flags); 169 spin_lock_irqsave(clk->lock, flags);
170 170
171 reg = readl(clk->pll_ctrl); 171 reg = clk_readl(clk->pll_ctrl);
172 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK; 172 reg |= PLLCTRL_RESET_MASK | PLLCTRL_PWRDWN_MASK;
173 writel(reg, clk->pll_ctrl); 173 clk_writel(reg, clk->pll_ctrl);
174 174
175 spin_unlock_irqrestore(clk->lock, flags); 175 spin_unlock_irqrestore(clk->lock, flags);
176} 176}
@@ -225,9 +225,9 @@ struct clk *clk_register_zynq_pll(const char *name, const char *parent,
225 225
226 spin_lock_irqsave(pll->lock, flags); 226 spin_lock_irqsave(pll->lock, flags);
227 227
228 reg = readl(pll->pll_ctrl); 228 reg = clk_readl(pll->pll_ctrl);
229 reg &= ~PLLCTRL_BPQUAL_MASK; 229 reg &= ~PLLCTRL_BPQUAL_MASK;
230 writel(reg, pll->pll_ctrl); 230 clk_writel(reg, pll->pll_ctrl);
231 231
232 spin_unlock_irqrestore(pll->lock, flags); 232 spin_unlock_irqrestore(pll->lock, flags);
233 233