1/*
2 * Helper routines for SuperH Clock Pulse Generator blocks (CPG).
3 *
4 *  Copyright (C) 2010  Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License.  See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/clk.h>
11#include <linux/compiler.h>
12#include <linux/slab.h>
13#include <linux/io.h>
14#include <linux/sh_clk.h>
15
16static int sh_clk_mstp32_enable(struct clk *clk)
17{
18	iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
19		  clk->mapped_reg);
20	return 0;
21}
22
23static void sh_clk_mstp32_disable(struct clk *clk)
24{
25	iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
26		  clk->mapped_reg);
27}
28
29static struct sh_clk_ops sh_clk_mstp32_clk_ops = {
30	.enable		= sh_clk_mstp32_enable,
31	.disable	= sh_clk_mstp32_disable,
32	.recalc		= followparent_recalc,
33};
34
35int __init sh_clk_mstp32_register(struct clk *clks, int nr)
36{
37	struct clk *clkp;
38	int ret = 0;
39	int k;
40
41	for (k = 0; !ret && (k < nr); k++) {
42		clkp = clks + k;
43		clkp->ops = &sh_clk_mstp32_clk_ops;
44		ret |= clk_register(clkp);
45	}
46
47	return ret;
48}
49
50static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate)
51{
52	return clk_rate_table_round(clk, clk->freq_table, rate);
53}
54
55static int sh_clk_div6_divisors[64] = {
56	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
57	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
58	33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
59	49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
60};
61
62static struct clk_div_mult_table sh_clk_div6_table = {
63	.divisors = sh_clk_div6_divisors,
64	.nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors),
65};
66
67static unsigned long sh_clk_div6_recalc(struct clk *clk)
68{
69	struct clk_div_mult_table *table = &sh_clk_div6_table;
70	unsigned int idx;
71
72	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
73			     table, NULL);
74
75	idx = ioread32(clk->mapped_reg) & 0x003f;
76
77	return clk->freq_table[idx].frequency;
78}
79
80static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent)
81{
82	struct clk_div_mult_table *table = &sh_clk_div6_table;
83	u32 value;
84	int ret, i;
85
86	if (!clk->parent_table || !clk->parent_num)
87		return -EINVAL;
88
89	/* Search the parent */
90	for (i = 0; i < clk->parent_num; i++)
91		if (clk->parent_table[i] == parent)
92			break;
93
94	if (i == clk->parent_num)
95		return -ENODEV;
96
97	ret = clk_reparent(clk, parent);
98	if (ret < 0)
99		return ret;
100
101	value = ioread32(clk->mapped_reg) &
102		~(((1 << clk->src_width) - 1) << clk->src_shift);
103
104	iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
105
106	/* Rebuild the frequency table */
107	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
108			     table, NULL);
109
110	return 0;
111}
112
113static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate)
114{
115	unsigned long value;
116	int idx;
117
118	idx = clk_rate_table_find(clk, clk->freq_table, rate);
119	if (idx < 0)
120		return idx;
121
122	value = ioread32(clk->mapped_reg);
123	value &= ~0x3f;
124	value |= idx;
125	iowrite32(value, clk->mapped_reg);
126	return 0;
127}
128
129static int sh_clk_div6_enable(struct clk *clk)
130{
131	unsigned long value;
132	int ret;
133
134	ret = sh_clk_div6_set_rate(clk, clk->rate);
135	if (ret == 0) {
136		value = ioread32(clk->mapped_reg);
137		value &= ~0x100; /* clear stop bit to enable clock */
138		iowrite32(value, clk->mapped_reg);
139	}
140	return ret;
141}
142
143static void sh_clk_div6_disable(struct clk *clk)
144{
145	unsigned long value;
146
147	value = ioread32(clk->mapped_reg);
148	value |= 0x100; /* stop clock */
149	value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
150	iowrite32(value, clk->mapped_reg);
151}
152
153static struct sh_clk_ops sh_clk_div6_clk_ops = {
154	.recalc		= sh_clk_div6_recalc,
155	.round_rate	= sh_clk_div_round_rate,
156	.set_rate	= sh_clk_div6_set_rate,
157	.enable		= sh_clk_div6_enable,
158	.disable	= sh_clk_div6_disable,
159};
160
161static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = {
162	.recalc		= sh_clk_div6_recalc,
163	.round_rate	= sh_clk_div_round_rate,
164	.set_rate	= sh_clk_div6_set_rate,
165	.enable		= sh_clk_div6_enable,
166	.disable	= sh_clk_div6_disable,
167	.set_parent	= sh_clk_div6_set_parent,
168};
169
170static int __init sh_clk_init_parent(struct clk *clk)
171{
172	u32 val;
173
174	if (clk->parent)
175		return 0;
176
177	if (!clk->parent_table || !clk->parent_num)
178		return 0;
179
180	if (!clk->src_width) {
181		pr_err("sh_clk_init_parent: cannot select parent clock\n");
182		return -EINVAL;
183	}
184
185	val  = (ioread32(clk->mapped_reg) >> clk->src_shift);
186	val &= (1 << clk->src_width) - 1;
187
188	if (val >= clk->parent_num) {
189		pr_err("sh_clk_init_parent: parent table size failed\n");
190		return -EINVAL;
191	}
192
193	clk_reparent(clk, clk->parent_table[val]);
194	if (!clk->parent) {
195		pr_err("sh_clk_init_parent: unable to set parent");
196		return -EINVAL;
197	}
198
199	return 0;
200}
201
202static int __init sh_clk_div6_register_ops(struct clk *clks, int nr,
203					   struct sh_clk_ops *ops)
204{
205	struct clk *clkp;
206	void *freq_table;
207	int nr_divs = sh_clk_div6_table.nr_divisors;
208	int freq_table_size = sizeof(struct cpufreq_frequency_table);
209	int ret = 0;
210	int k;
211
212	freq_table_size *= (nr_divs + 1);
213	freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
214	if (!freq_table) {
215		pr_err("sh_clk_div6_register: unable to alloc memory\n");
216		return -ENOMEM;
217	}
218
219	for (k = 0; !ret && (k < nr); k++) {
220		clkp = clks + k;
221
222		clkp->ops = ops;
223		clkp->freq_table = freq_table + (k * freq_table_size);
224		clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
225		ret = clk_register(clkp);
226		if (ret < 0)
227			break;
228
229		ret = sh_clk_init_parent(clkp);
230	}
231
232	return ret;
233}
234
235int __init sh_clk_div6_register(struct clk *clks, int nr)
236{
237	return sh_clk_div6_register_ops(clks, nr, &sh_clk_div6_clk_ops);
238}
239
240int __init sh_clk_div6_reparent_register(struct clk *clks, int nr)
241{
242	return sh_clk_div6_register_ops(clks, nr,
243					&sh_clk_div6_reparent_clk_ops);
244}
245
246static unsigned long sh_clk_div4_recalc(struct clk *clk)
247{
248	struct clk_div4_table *d4t = clk->priv;
249	struct clk_div_mult_table *table = d4t->div_mult_table;
250	unsigned int idx;
251
252	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
253			     table, &clk->arch_flags);
254
255	idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
256
257	return clk->freq_table[idx].frequency;
258}
259
260static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent)
261{
262	struct clk_div4_table *d4t = clk->priv;
263	struct clk_div_mult_table *table = d4t->div_mult_table;
264	u32 value;
265	int ret;
266
267	/* we really need a better way to determine parent index, but for
268	 * now assume internal parent comes with CLK_ENABLE_ON_INIT set,
269	 * no CLK_ENABLE_ON_INIT means external clock...
270	 */
271
272	if (parent->flags & CLK_ENABLE_ON_INIT)
273		value = ioread32(clk->mapped_reg) & ~(1 << 7);
274	else
275		value = ioread32(clk->mapped_reg) | (1 << 7);
276
277	ret = clk_reparent(clk, parent);
278	if (ret < 0)
279		return ret;
280
281	iowrite32(value, clk->mapped_reg);
282
283	/* Rebiuld the frequency table */
284	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
285			     table, &clk->arch_flags);
286
287	return 0;
288}
289
290static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate)
291{
292	struct clk_div4_table *d4t = clk->priv;
293	unsigned long value;
294	int idx = clk_rate_table_find(clk, clk->freq_table, rate);
295	if (idx < 0)
296		return idx;
297
298	value = ioread32(clk->mapped_reg);
299	value &= ~(0xf << clk->enable_bit);
300	value |= (idx << clk->enable_bit);
301	iowrite32(value, clk->mapped_reg);
302
303	if (d4t->kick)
304		d4t->kick(clk);
305
306	return 0;
307}
308
309static int sh_clk_div4_enable(struct clk *clk)
310{
311	iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
312	return 0;
313}
314
315static void sh_clk_div4_disable(struct clk *clk)
316{
317	iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
318}
319
320static struct sh_clk_ops sh_clk_div4_clk_ops = {
321	.recalc		= sh_clk_div4_recalc,
322	.set_rate	= sh_clk_div4_set_rate,
323	.round_rate	= sh_clk_div_round_rate,
324};
325
326static struct sh_clk_ops sh_clk_div4_enable_clk_ops = {
327	.recalc		= sh_clk_div4_recalc,
328	.set_rate	= sh_clk_div4_set_rate,
329	.round_rate	= sh_clk_div_round_rate,
330	.enable		= sh_clk_div4_enable,
331	.disable	= sh_clk_div4_disable,
332};
333
334static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = {
335	.recalc		= sh_clk_div4_recalc,
336	.set_rate	= sh_clk_div4_set_rate,
337	.round_rate	= sh_clk_div_round_rate,
338	.enable		= sh_clk_div4_enable,
339	.disable	= sh_clk_div4_disable,
340	.set_parent	= sh_clk_div4_set_parent,
341};
342
343static int __init sh_clk_div4_register_ops(struct clk *clks, int nr,
344			struct clk_div4_table *table, struct sh_clk_ops *ops)
345{
346	struct clk *clkp;
347	void *freq_table;
348	int nr_divs = table->div_mult_table->nr_divisors;
349	int freq_table_size = sizeof(struct cpufreq_frequency_table);
350	int ret = 0;
351	int k;
352
353	freq_table_size *= (nr_divs + 1);
354	freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL);
355	if (!freq_table) {
356		pr_err("sh_clk_div4_register: unable to alloc memory\n");
357		return -ENOMEM;
358	}
359
360	for (k = 0; !ret && (k < nr); k++) {
361		clkp = clks + k;
362
363		clkp->ops = ops;
364		clkp->priv = table;
365
366		clkp->freq_table = freq_table + (k * freq_table_size);
367		clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END;
368
369		ret = clk_register(clkp);
370	}
371
372	return ret;
373}
374
375int __init sh_clk_div4_register(struct clk *clks, int nr,
376				struct clk_div4_table *table)
377{
378	return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops);
379}
380
381int __init sh_clk_div4_enable_register(struct clk *clks, int nr,
382				struct clk_div4_table *table)
383{
384	return sh_clk_div4_register_ops(clks, nr, table,
385					&sh_clk_div4_enable_clk_ops);
386}
387
388int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
389				struct clk_div4_table *table)
390{
391	return sh_clk_div4_register_ops(clks, nr, table,
392					&sh_clk_div4_reparent_clk_ops);
393}
394