• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/mips/jz4740/
1/*
2 *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 *  JZ4740 SoC clock support
4 *
5 *  This program is free software; you can redistribute it and/or modify it
6 *  under  the terms of the GNU General  Public License as published by the
7 *  Free Software Foundation;  either version 2 of the License, or (at your
8 *  option) any later version.
9 *
10 *  You should have received a copy of the GNU General Public License along
11 *  with this program; if not, write to the Free Software Foundation, Inc.,
12 *  675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/errno.h>
18#include <linux/clk.h>
19#include <linux/spinlock.h>
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/list.h>
23#include <linux/err.h>
24
25#include <asm/mach-jz4740/clock.h>
26#include <asm/mach-jz4740/base.h>
27
28#include "clock.h"
29
30#define JZ_REG_CLOCK_CTRL	0x00
31#define JZ_REG_CLOCK_LOW_POWER	0x04
32#define JZ_REG_CLOCK_PLL	0x10
33#define JZ_REG_CLOCK_GATE	0x20
34#define JZ_REG_CLOCK_SLEEP_CTRL	0x24
35#define JZ_REG_CLOCK_I2S	0x60
36#define JZ_REG_CLOCK_LCD	0x64
37#define JZ_REG_CLOCK_MMC	0x68
38#define JZ_REG_CLOCK_UHC	0x6C
39#define JZ_REG_CLOCK_SPI	0x74
40
41#define JZ_CLOCK_CTRL_I2S_SRC_PLL	BIT(31)
42#define JZ_CLOCK_CTRL_KO_ENABLE		BIT(30)
43#define JZ_CLOCK_CTRL_UDC_SRC_PLL	BIT(29)
44#define JZ_CLOCK_CTRL_UDIV_MASK		0x1f800000
45#define JZ_CLOCK_CTRL_CHANGE_ENABLE	BIT(22)
46#define JZ_CLOCK_CTRL_PLL_HALF		BIT(21)
47#define JZ_CLOCK_CTRL_LDIV_MASK		0x001f0000
48#define JZ_CLOCK_CTRL_UDIV_OFFSET	23
49#define JZ_CLOCK_CTRL_LDIV_OFFSET	16
50#define JZ_CLOCK_CTRL_MDIV_OFFSET	12
51#define JZ_CLOCK_CTRL_PDIV_OFFSET	 8
52#define JZ_CLOCK_CTRL_HDIV_OFFSET	 4
53#define JZ_CLOCK_CTRL_CDIV_OFFSET	 0
54
55#define JZ_CLOCK_GATE_UART0	BIT(0)
56#define JZ_CLOCK_GATE_TCU	BIT(1)
57#define JZ_CLOCK_GATE_RTC	BIT(2)
58#define JZ_CLOCK_GATE_I2C	BIT(3)
59#define JZ_CLOCK_GATE_SPI	BIT(4)
60#define JZ_CLOCK_GATE_AIC	BIT(5)
61#define JZ_CLOCK_GATE_I2S	BIT(6)
62#define JZ_CLOCK_GATE_MMC	BIT(7)
63#define JZ_CLOCK_GATE_ADC	BIT(8)
64#define JZ_CLOCK_GATE_CIM	BIT(9)
65#define JZ_CLOCK_GATE_LCD	BIT(10)
66#define JZ_CLOCK_GATE_UDC	BIT(11)
67#define JZ_CLOCK_GATE_DMAC	BIT(12)
68#define JZ_CLOCK_GATE_IPU	BIT(13)
69#define JZ_CLOCK_GATE_UHC	BIT(14)
70#define JZ_CLOCK_GATE_UART1	BIT(15)
71
72#define JZ_CLOCK_I2S_DIV_MASK		0x01ff
73
74#define JZ_CLOCK_LCD_DIV_MASK		0x01ff
75
76#define JZ_CLOCK_MMC_DIV_MASK		0x001f
77
78#define JZ_CLOCK_UHC_DIV_MASK		0x000f
79
80#define JZ_CLOCK_SPI_SRC_PLL		BIT(31)
81#define JZ_CLOCK_SPI_DIV_MASK		0x000f
82
83#define JZ_CLOCK_PLL_M_MASK		0x01ff
84#define JZ_CLOCK_PLL_N_MASK		0x001f
85#define JZ_CLOCK_PLL_OD_MASK		0x0003
86#define JZ_CLOCK_PLL_STABLE		BIT(10)
87#define JZ_CLOCK_PLL_BYPASS		BIT(9)
88#define JZ_CLOCK_PLL_ENABLED		BIT(8)
89#define JZ_CLOCK_PLL_STABLIZE_MASK	0x000f
90#define JZ_CLOCK_PLL_M_OFFSET		23
91#define JZ_CLOCK_PLL_N_OFFSET		18
92#define JZ_CLOCK_PLL_OD_OFFSET		16
93
94#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
95#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
96
97#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
98#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
99
100static void __iomem *jz_clock_base;
101static spinlock_t jz_clock_lock;
102static LIST_HEAD(jz_clocks);
103
104struct main_clk {
105	struct clk clk;
106	uint32_t div_offset;
107};
108
109struct divided_clk {
110	struct clk clk;
111	uint32_t reg;
112	uint32_t mask;
113};
114
115struct static_clk {
116	struct clk clk;
117	unsigned long rate;
118};
119
120static uint32_t jz_clk_reg_read(int reg)
121{
122	return readl(jz_clock_base + reg);
123}
124
125static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
126{
127	uint32_t val2;
128
129	spin_lock(&jz_clock_lock);
130	val2 = readl(jz_clock_base + reg);
131	val2 &= ~mask;
132	val2 |= val;
133	writel(val2, jz_clock_base + reg);
134	spin_unlock(&jz_clock_lock);
135}
136
137static void jz_clk_reg_set_bits(int reg, uint32_t mask)
138{
139	uint32_t val;
140
141	spin_lock(&jz_clock_lock);
142	val = readl(jz_clock_base + reg);
143	val |= mask;
144	writel(val, jz_clock_base + reg);
145	spin_unlock(&jz_clock_lock);
146}
147
148static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
149{
150	uint32_t val;
151
152	spin_lock(&jz_clock_lock);
153	val = readl(jz_clock_base + reg);
154	val &= ~mask;
155	writel(val, jz_clock_base + reg);
156	spin_unlock(&jz_clock_lock);
157}
158
159static int jz_clk_enable_gating(struct clk *clk)
160{
161	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
162		return -EINVAL;
163
164	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
165	return 0;
166}
167
168static int jz_clk_disable_gating(struct clk *clk)
169{
170	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
171		return -EINVAL;
172
173	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
174	return 0;
175}
176
177static int jz_clk_is_enabled_gating(struct clk *clk)
178{
179	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
180		return 1;
181
182	return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
183}
184
185static unsigned long jz_clk_static_get_rate(struct clk *clk)
186{
187	return ((struct static_clk *)clk)->rate;
188}
189
190static int jz_clk_ko_enable(struct clk *clk)
191{
192	jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
193	return 0;
194}
195
196static int jz_clk_ko_disable(struct clk *clk)
197{
198	jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
199	return 0;
200}
201
202static int jz_clk_ko_is_enabled(struct clk *clk)
203{
204	return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
205}
206
207static const int pllno[] = {1, 2, 2, 4};
208
209static unsigned long jz_clk_pll_get_rate(struct clk *clk)
210{
211	uint32_t val;
212	int m;
213	int n;
214	int od;
215
216	val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
217
218	if (val & JZ_CLOCK_PLL_BYPASS)
219		return clk_get_rate(clk->parent);
220
221	m = ((val >> 23) & 0x1ff) + 2;
222	n = ((val >> 18) & 0x1f) + 2;
223	od = (val >> 16) & 0x3;
224
225	return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
226}
227
228static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
229{
230	uint32_t reg;
231
232	reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
233	if (reg & JZ_CLOCK_CTRL_PLL_HALF)
234		return jz_clk_pll_get_rate(clk->parent);
235	return jz_clk_pll_get_rate(clk->parent) >> 1;
236}
237
238static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
239
240static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
241{
242	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
243	int div;
244
245	div = parent_rate / rate;
246	if (div > 32)
247		return parent_rate / 32;
248	else if (div < 1)
249		return parent_rate;
250
251	div &= (0x3 << (ffs(div) - 1));
252
253	return parent_rate / div;
254}
255
256static unsigned long jz_clk_main_get_rate(struct clk *clk)
257{
258	struct main_clk *mclk = (struct main_clk *)clk;
259	uint32_t div;
260
261	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
262
263	div >>= mclk->div_offset;
264	div &= 0xf;
265
266	if (div >= ARRAY_SIZE(jz_clk_main_divs))
267		div = ARRAY_SIZE(jz_clk_main_divs) - 1;
268
269	return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
270}
271
272static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
273{
274	struct main_clk *mclk = (struct main_clk *)clk;
275	int i;
276	int div;
277	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
278
279	rate = jz_clk_main_round_rate(clk, rate);
280
281	div = parent_rate / rate;
282
283	i = (ffs(div) - 1) << 1;
284	if (i > 0 && !(div & BIT(i-1)))
285		i -= 1;
286
287	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
288				0xf << mclk->div_offset);
289
290	return 0;
291}
292
293static struct clk_ops jz_clk_static_ops = {
294	.get_rate = jz_clk_static_get_rate,
295	.enable = jz_clk_enable_gating,
296	.disable = jz_clk_disable_gating,
297	.is_enabled = jz_clk_is_enabled_gating,
298};
299
300static struct static_clk jz_clk_ext = {
301	.clk = {
302		.name = "ext",
303		.gate_bit = JZ4740_CLK_NOT_GATED,
304		.ops = &jz_clk_static_ops,
305	},
306};
307
308static struct clk_ops jz_clk_pll_ops = {
309	.get_rate = jz_clk_pll_get_rate,
310};
311
312static struct clk jz_clk_pll = {
313	.name = "pll",
314	.parent = &jz_clk_ext.clk,
315	.ops = &jz_clk_pll_ops,
316};
317
318static struct clk_ops jz_clk_pll_half_ops = {
319	.get_rate = jz_clk_pll_half_get_rate,
320};
321
322static struct clk jz_clk_pll_half = {
323	.name = "pll half",
324	.parent = &jz_clk_pll,
325	.ops = &jz_clk_pll_half_ops,
326};
327
328static const struct clk_ops jz_clk_main_ops = {
329	.get_rate = jz_clk_main_get_rate,
330	.set_rate = jz_clk_main_set_rate,
331	.round_rate = jz_clk_main_round_rate,
332};
333
334static struct main_clk jz_clk_cpu = {
335	.clk = {
336		.name = "cclk",
337		.parent = &jz_clk_pll,
338		.ops = &jz_clk_main_ops,
339	},
340	.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
341};
342
343static struct main_clk jz_clk_memory = {
344	.clk = {
345		.name = "mclk",
346		.parent = &jz_clk_pll,
347		.ops = &jz_clk_main_ops,
348	},
349	.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
350};
351
352static struct main_clk jz_clk_high_speed_peripheral = {
353	.clk = {
354		.name = "hclk",
355		.parent = &jz_clk_pll,
356		.ops = &jz_clk_main_ops,
357	},
358	.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
359};
360
361
362static struct main_clk jz_clk_low_speed_peripheral = {
363	.clk = {
364		.name = "pclk",
365		.parent = &jz_clk_pll,
366		.ops = &jz_clk_main_ops,
367	},
368	.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
369};
370
371static const struct clk_ops jz_clk_ko_ops = {
372	.enable = jz_clk_ko_enable,
373	.disable = jz_clk_ko_disable,
374	.is_enabled = jz_clk_ko_is_enabled,
375};
376
377static struct clk jz_clk_ko = {
378	.name = "cko",
379	.parent = &jz_clk_memory.clk,
380	.ops = &jz_clk_ko_ops,
381};
382
383static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
384{
385	if (parent == &jz_clk_pll)
386		jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
387	else if (parent == &jz_clk_ext.clk)
388		jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
389	else
390		return -EINVAL;
391
392	clk->parent = parent;
393
394	return 0;
395}
396
397static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
398{
399	if (parent == &jz_clk_pll_half)
400		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
401	else if (parent == &jz_clk_ext.clk)
402		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
403	else
404		return -EINVAL;
405
406	clk->parent = parent;
407
408	return 0;
409}
410
411static int jz_clk_udc_enable(struct clk *clk)
412{
413	jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
414			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
415
416	return 0;
417}
418
419static int jz_clk_udc_disable(struct clk *clk)
420{
421	jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
422			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
423
424	return 0;
425}
426
427static int jz_clk_udc_is_enabled(struct clk *clk)
428{
429	return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
430			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
431}
432
433static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
434{
435	if (parent == &jz_clk_pll_half)
436		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
437	else if (parent == &jz_clk_ext.clk)
438		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
439	else
440		return -EINVAL;
441
442	clk->parent = parent;
443
444	return 0;
445}
446
447static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
448{
449	int div;
450
451	if (clk->parent == &jz_clk_ext.clk)
452		return -EINVAL;
453
454	div = clk_get_rate(clk->parent) / rate - 1;
455
456	if (div < 0)
457		div = 0;
458	else if (div > 63)
459		div = 63;
460
461	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
462				JZ_CLOCK_CTRL_UDIV_MASK);
463	return 0;
464}
465
466static unsigned long jz_clk_udc_get_rate(struct clk *clk)
467{
468	int div;
469
470	if (clk->parent == &jz_clk_ext.clk)
471		return clk_get_rate(clk->parent);
472
473	div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
474	div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
475	div += 1;
476
477	return clk_get_rate(clk->parent) / div;
478}
479
480static unsigned long jz_clk_divided_get_rate(struct clk *clk)
481{
482	struct divided_clk *dclk = (struct divided_clk *)clk;
483	int div;
484
485	if (clk->parent == &jz_clk_ext.clk)
486		return clk_get_rate(clk->parent);
487
488	div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
489
490	return clk_get_rate(clk->parent) / div;
491}
492
493static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
494{
495	struct divided_clk *dclk = (struct divided_clk *)clk;
496	int div;
497
498	if (clk->parent == &jz_clk_ext.clk)
499		return -EINVAL;
500
501	div = clk_get_rate(clk->parent) / rate - 1;
502
503	if (div < 0)
504		div = 0;
505	else if (div > dclk->mask)
506		div = dclk->mask;
507
508	jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
509
510	return 0;
511}
512
513static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
514{
515	int div;
516	unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
517
518	if (rate > 150000000)
519		return 150000000;
520
521	div = parent_rate / rate;
522	if (div < 1)
523		div = 1;
524	else if (div > 32)
525		div = 32;
526
527	return parent_rate / div;
528}
529
530static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
531{
532	int div;
533
534	if (rate > 150000000)
535		return -EINVAL;
536
537	div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
538	if (div < 0)
539		div = 0;
540	else if (div > 31)
541		div = 31;
542
543	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
544				JZ_CLOCK_CTRL_LDIV_MASK);
545
546	return 0;
547}
548
549static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
550{
551	int div;
552
553	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
554	div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
555
556	return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
557}
558
559static const struct clk_ops jz_clk_ops_ld = {
560	.set_rate = jz_clk_ldclk_set_rate,
561	.get_rate = jz_clk_ldclk_get_rate,
562	.round_rate = jz_clk_ldclk_round_rate,
563	.enable = jz_clk_enable_gating,
564	.disable = jz_clk_disable_gating,
565	.is_enabled = jz_clk_is_enabled_gating,
566};
567
568static struct clk jz_clk_ld = {
569	.name = "lcd",
570	.gate_bit = JZ_CLOCK_GATE_LCD,
571	.parent = &jz_clk_pll_half,
572	.ops = &jz_clk_ops_ld,
573};
574
575static const struct clk_ops jz_clk_i2s_ops = {
576	.set_rate = jz_clk_divided_set_rate,
577	.get_rate = jz_clk_divided_get_rate,
578	.enable = jz_clk_enable_gating,
579	.disable = jz_clk_disable_gating,
580	.is_enabled = jz_clk_is_enabled_gating,
581	.set_parent = jz_clk_i2s_set_parent,
582};
583
584static const struct clk_ops jz_clk_spi_ops = {
585	.set_rate = jz_clk_divided_set_rate,
586	.get_rate = jz_clk_divided_get_rate,
587	.enable = jz_clk_enable_gating,
588	.disable = jz_clk_disable_gating,
589	.is_enabled = jz_clk_is_enabled_gating,
590	.set_parent = jz_clk_spi_set_parent,
591};
592
593static const struct clk_ops jz_clk_divided_ops = {
594	.set_rate = jz_clk_divided_set_rate,
595	.get_rate = jz_clk_divided_get_rate,
596	.enable = jz_clk_enable_gating,
597	.disable = jz_clk_disable_gating,
598	.is_enabled = jz_clk_is_enabled_gating,
599};
600
601static struct divided_clk jz4740_clock_divided_clks[] = {
602	[0] = {
603		.clk = {
604			.name = "i2s",
605			.parent = &jz_clk_ext.clk,
606			.gate_bit = JZ_CLOCK_GATE_I2S,
607			.ops = &jz_clk_i2s_ops,
608		},
609		.reg = JZ_REG_CLOCK_I2S,
610		.mask = JZ_CLOCK_I2S_DIV_MASK,
611	},
612	[1] = {
613		.clk = {
614			.name = "spi",
615			.parent = &jz_clk_ext.clk,
616			.gate_bit = JZ_CLOCK_GATE_SPI,
617			.ops = &jz_clk_spi_ops,
618		},
619		.reg = JZ_REG_CLOCK_SPI,
620		.mask = JZ_CLOCK_SPI_DIV_MASK,
621	},
622	[2] = {
623		.clk = {
624			.name = "lcd_pclk",
625			.parent = &jz_clk_pll_half,
626			.gate_bit = JZ4740_CLK_NOT_GATED,
627			.ops = &jz_clk_divided_ops,
628		},
629		.reg = JZ_REG_CLOCK_LCD,
630		.mask = JZ_CLOCK_LCD_DIV_MASK,
631	},
632	[3] = {
633		.clk = {
634			.name = "mmc",
635			.parent = &jz_clk_pll_half,
636			.gate_bit = JZ_CLOCK_GATE_MMC,
637			.ops = &jz_clk_divided_ops,
638		},
639		.reg = JZ_REG_CLOCK_MMC,
640		.mask = JZ_CLOCK_MMC_DIV_MASK,
641	},
642	[4] = {
643		.clk = {
644			.name = "uhc",
645			.parent = &jz_clk_pll_half,
646			.gate_bit = JZ_CLOCK_GATE_UHC,
647			.ops = &jz_clk_divided_ops,
648		},
649		.reg = JZ_REG_CLOCK_UHC,
650		.mask = JZ_CLOCK_UHC_DIV_MASK,
651	},
652};
653
654static const struct clk_ops jz_clk_udc_ops = {
655	.set_parent = jz_clk_udc_set_parent,
656	.set_rate = jz_clk_udc_set_rate,
657	.get_rate = jz_clk_udc_get_rate,
658	.enable = jz_clk_udc_enable,
659	.disable = jz_clk_udc_disable,
660	.is_enabled = jz_clk_udc_is_enabled,
661};
662
663static const struct clk_ops jz_clk_simple_ops = {
664	.enable = jz_clk_enable_gating,
665	.disable = jz_clk_disable_gating,
666	.is_enabled = jz_clk_is_enabled_gating,
667};
668
669static struct clk jz4740_clock_simple_clks[] = {
670	[0] = {
671		.name = "udc",
672		.parent = &jz_clk_ext.clk,
673		.ops = &jz_clk_udc_ops,
674	},
675	[1] = {
676		.name = "uart0",
677		.parent = &jz_clk_ext.clk,
678		.gate_bit = JZ_CLOCK_GATE_UART0,
679		.ops = &jz_clk_simple_ops,
680	},
681	[2] = {
682		.name = "uart1",
683		.parent = &jz_clk_ext.clk,
684		.gate_bit = JZ_CLOCK_GATE_UART1,
685		.ops = &jz_clk_simple_ops,
686	},
687	[3] = {
688		.name = "dma",
689		.parent = &jz_clk_high_speed_peripheral.clk,
690		.gate_bit = JZ_CLOCK_GATE_UART0,
691		.ops = &jz_clk_simple_ops,
692	},
693	[4] = {
694		.name = "ipu",
695		.parent = &jz_clk_high_speed_peripheral.clk,
696		.gate_bit = JZ_CLOCK_GATE_IPU,
697		.ops = &jz_clk_simple_ops,
698	},
699	[5] = {
700		.name = "adc",
701		.parent = &jz_clk_ext.clk,
702		.gate_bit = JZ_CLOCK_GATE_ADC,
703		.ops = &jz_clk_simple_ops,
704	},
705	[6] = {
706		.name = "i2c",
707		.parent = &jz_clk_ext.clk,
708		.gate_bit = JZ_CLOCK_GATE_I2C,
709		.ops = &jz_clk_simple_ops,
710	},
711	[7] = {
712		.name = "aic",
713		.parent = &jz_clk_ext.clk,
714		.gate_bit = JZ_CLOCK_GATE_AIC,
715		.ops = &jz_clk_simple_ops,
716	},
717};
718
719static struct static_clk jz_clk_rtc = {
720	.clk = {
721		.name = "rtc",
722		.gate_bit = JZ_CLOCK_GATE_RTC,
723		.ops = &jz_clk_static_ops,
724	},
725	.rate = 32768,
726};
727
728int clk_enable(struct clk *clk)
729{
730	if (!clk->ops->enable)
731		return -EINVAL;
732
733	return clk->ops->enable(clk);
734}
735EXPORT_SYMBOL_GPL(clk_enable);
736
737void clk_disable(struct clk *clk)
738{
739	if (clk->ops->disable)
740		clk->ops->disable(clk);
741}
742EXPORT_SYMBOL_GPL(clk_disable);
743
744int clk_is_enabled(struct clk *clk)
745{
746	if (clk->ops->is_enabled)
747		return clk->ops->is_enabled(clk);
748
749	return 1;
750}
751
752unsigned long clk_get_rate(struct clk *clk)
753{
754	if (clk->ops->get_rate)
755		return clk->ops->get_rate(clk);
756	if (clk->parent)
757		return clk_get_rate(clk->parent);
758
759	return -EINVAL;
760}
761EXPORT_SYMBOL_GPL(clk_get_rate);
762
763int clk_set_rate(struct clk *clk, unsigned long rate)
764{
765	if (!clk->ops->set_rate)
766		return -EINVAL;
767	return clk->ops->set_rate(clk, rate);
768}
769EXPORT_SYMBOL_GPL(clk_set_rate);
770
771long clk_round_rate(struct clk *clk, unsigned long rate)
772{
773	if (clk->ops->round_rate)
774		return clk->ops->round_rate(clk, rate);
775
776	return -EINVAL;
777}
778EXPORT_SYMBOL_GPL(clk_round_rate);
779
780int clk_set_parent(struct clk *clk, struct clk *parent)
781{
782	int ret;
783	int enabled;
784
785	if (!clk->ops->set_parent)
786		return -EINVAL;
787
788	enabled = clk_is_enabled(clk);
789	if (enabled)
790		clk_disable(clk);
791	ret = clk->ops->set_parent(clk, parent);
792	if (enabled)
793		clk_enable(clk);
794
795	jz4740_clock_debugfs_update_parent(clk);
796
797	return ret;
798}
799EXPORT_SYMBOL_GPL(clk_set_parent);
800
801struct clk *clk_get(struct device *dev, const char *name)
802{
803	struct clk *clk;
804
805	list_for_each_entry(clk, &jz_clocks, list) {
806		if (strcmp(clk->name, name) == 0)
807			return clk;
808	}
809	return ERR_PTR(-ENXIO);
810}
811EXPORT_SYMBOL_GPL(clk_get);
812
813void clk_put(struct clk *clk)
814{
815}
816EXPORT_SYMBOL_GPL(clk_put);
817
818static inline void clk_add(struct clk *clk)
819{
820	list_add_tail(&clk->list, &jz_clocks);
821
822	jz4740_clock_debugfs_add_clk(clk);
823}
824
825static void clk_register_clks(void)
826{
827	size_t i;
828
829	clk_add(&jz_clk_ext.clk);
830	clk_add(&jz_clk_pll);
831	clk_add(&jz_clk_pll_half);
832	clk_add(&jz_clk_cpu.clk);
833	clk_add(&jz_clk_high_speed_peripheral.clk);
834	clk_add(&jz_clk_low_speed_peripheral.clk);
835	clk_add(&jz_clk_ko);
836	clk_add(&jz_clk_ld);
837	clk_add(&jz_clk_rtc.clk);
838
839	for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
840		clk_add(&jz4740_clock_divided_clks[i].clk);
841
842	for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
843		clk_add(&jz4740_clock_simple_clks[i]);
844}
845
846void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
847{
848	switch (mode) {
849	case JZ4740_WAIT_MODE_IDLE:
850		jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
851		break;
852	case JZ4740_WAIT_MODE_SLEEP:
853		jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
854		break;
855	}
856}
857
858void jz4740_clock_udc_disable_auto_suspend(void)
859{
860	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
861}
862EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
863
864void jz4740_clock_udc_enable_auto_suspend(void)
865{
866	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
867}
868EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
869
870void jz4740_clock_suspend(void)
871{
872	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
873		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
874
875	jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
876}
877
878void jz4740_clock_resume(void)
879{
880	uint32_t pll;
881
882	jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
883
884	do {
885		pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
886	} while (!(pll & JZ_CLOCK_PLL_STABLE));
887
888	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
889		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
890}
891
892static int jz4740_clock_init(void)
893{
894	uint32_t val;
895
896	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
897	if (!jz_clock_base)
898		return -EBUSY;
899
900	spin_lock_init(&jz_clock_lock);
901
902	jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
903	jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
904
905	val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
906
907	if (val & JZ_CLOCK_SPI_SRC_PLL)
908		jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
909
910	val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
911
912	if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
913		jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
914
915	if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
916		jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
917
918	jz4740_clock_debugfs_init();
919
920	clk_register_clks();
921
922	return 0;
923}
924arch_initcall(jz4740_clock_init);
925