~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to arch/arm/mach-shmobile/clock-sh7372.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SH7372 clock framework support
 
3
 *
 
4
 * Copyright (C) 2010 Magnus Damm
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License
 
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
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 */
 
19
#include <linux/init.h>
 
20
#include <linux/kernel.h>
 
21
#include <linux/io.h>
 
22
#include <linux/sh_clk.h>
 
23
#include <linux/clkdev.h>
 
24
#include <mach/common.h>
 
25
 
 
26
/* SH7372 registers */
 
27
#define FRQCRA          0xe6150000
 
28
#define FRQCRB          0xe6150004
 
29
#define FRQCRC          0xe61500e0
 
30
#define FRQCRD          0xe61500e4
 
31
#define VCLKCR1         0xe6150008
 
32
#define VCLKCR2         0xe615000c
 
33
#define VCLKCR3         0xe615001c
 
34
#define FMSICKCR        0xe6150010
 
35
#define FMSOCKCR        0xe6150014
 
36
#define FSIACKCR        0xe6150018
 
37
#define FSIBCKCR        0xe6150090
 
38
#define SUBCKCR         0xe6150080
 
39
#define SPUCKCR         0xe6150084
 
40
#define VOUCKCR         0xe6150088
 
41
#define HDMICKCR        0xe6150094
 
42
#define DSITCKCR        0xe6150060
 
43
#define DSI0PCKCR       0xe6150064
 
44
#define DSI1PCKCR       0xe6150098
 
45
#define PLLC01CR        0xe6150028
 
46
#define PLLC2CR         0xe615002c
 
47
#define SMSTPCR0        0xe6150130
 
48
#define SMSTPCR1        0xe6150134
 
49
#define SMSTPCR2        0xe6150138
 
50
#define SMSTPCR3        0xe615013c
 
51
#define SMSTPCR4        0xe6150140
 
52
 
 
53
#define FSIDIVA         0xFE1F8000
 
54
#define FSIDIVB         0xFE1F8008
 
55
 
 
56
/* Platforms must set frequency on their DV_CLKI pin */
 
57
struct clk sh7372_dv_clki_clk = {
 
58
};
 
59
 
 
60
/* Fixed 32 KHz root clock from EXTALR pin */
 
61
static struct clk r_clk = {
 
62
        .rate           = 32768,
 
63
};
 
64
 
 
65
/*
 
66
 * 26MHz default rate for the EXTAL1 root input clock.
 
67
 * If needed, reset this with clk_set_rate() from the platform code.
 
68
 */
 
69
struct clk sh7372_extal1_clk = {
 
70
        .rate           = 26000000,
 
71
};
 
72
 
 
73
/*
 
74
 * 48MHz default rate for the EXTAL2 root input clock.
 
75
 * If needed, reset this with clk_set_rate() from the platform code.
 
76
 */
 
77
struct clk sh7372_extal2_clk = {
 
78
        .rate           = 48000000,
 
79
};
 
80
 
 
81
/* A fixed divide-by-2 block */
 
82
static unsigned long div2_recalc(struct clk *clk)
 
83
{
 
84
        return clk->parent->rate / 2;
 
85
}
 
86
 
 
87
static struct clk_ops div2_clk_ops = {
 
88
        .recalc         = div2_recalc,
 
89
};
 
90
 
 
91
/* Divide dv_clki by two */
 
92
struct clk sh7372_dv_clki_div2_clk = {
 
93
        .ops            = &div2_clk_ops,
 
94
        .parent         = &sh7372_dv_clki_clk,
 
95
};
 
96
 
 
97
/* Divide extal1 by two */
 
98
static struct clk extal1_div2_clk = {
 
99
        .ops            = &div2_clk_ops,
 
100
        .parent         = &sh7372_extal1_clk,
 
101
};
 
102
 
 
103
/* Divide extal2 by two */
 
104
static struct clk extal2_div2_clk = {
 
105
        .ops            = &div2_clk_ops,
 
106
        .parent         = &sh7372_extal2_clk,
 
107
};
 
108
 
 
109
/* Divide extal2 by four */
 
110
static struct clk extal2_div4_clk = {
 
111
        .ops            = &div2_clk_ops,
 
112
        .parent         = &extal2_div2_clk,
 
113
};
 
114
 
 
115
/* PLLC0 and PLLC1 */
 
116
static unsigned long pllc01_recalc(struct clk *clk)
 
117
{
 
118
        unsigned long mult = 1;
 
119
 
 
120
        if (__raw_readl(PLLC01CR) & (1 << 14))
 
121
                mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
 
122
 
 
123
        return clk->parent->rate * mult;
 
124
}
 
125
 
 
126
static struct clk_ops pllc01_clk_ops = {
 
127
        .recalc         = pllc01_recalc,
 
128
};
 
129
 
 
130
static struct clk pllc0_clk = {
 
131
        .ops            = &pllc01_clk_ops,
 
132
        .flags          = CLK_ENABLE_ON_INIT,
 
133
        .parent         = &extal1_div2_clk,
 
134
        .enable_reg     = (void __iomem *)FRQCRC,
 
135
};
 
136
 
 
137
static struct clk pllc1_clk = {
 
138
        .ops            = &pllc01_clk_ops,
 
139
        .flags          = CLK_ENABLE_ON_INIT,
 
140
        .parent         = &extal1_div2_clk,
 
141
        .enable_reg     = (void __iomem *)FRQCRA,
 
142
};
 
143
 
 
144
/* Divide PLLC1 by two */
 
145
static struct clk pllc1_div2_clk = {
 
146
        .ops            = &div2_clk_ops,
 
147
        .parent         = &pllc1_clk,
 
148
};
 
149
 
 
150
/* PLLC2 */
 
151
 
 
152
/* Indices are important - they are the actual src selecting values */
 
153
static struct clk *pllc2_parent[] = {
 
154
        [0] = &extal1_div2_clk,
 
155
        [1] = &extal2_div2_clk,
 
156
        [2] = &sh7372_dv_clki_div2_clk,
 
157
};
 
158
 
 
159
/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
 
160
static struct cpufreq_frequency_table pllc2_freq_table[29];
 
161
 
 
162
static void pllc2_table_rebuild(struct clk *clk)
 
163
{
 
164
        int i;
 
165
 
 
166
        /* Initialise PLLC2 frequency table */
 
167
        for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
 
168
                pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
 
169
                pllc2_freq_table[i].index = i;
 
170
        }
 
171
 
 
172
        /* This is a special entry - switching PLL off makes it a repeater */
 
173
        pllc2_freq_table[i].frequency = clk->parent->rate;
 
174
        pllc2_freq_table[i].index = i;
 
175
 
 
176
        pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
 
177
        pllc2_freq_table[i].index = i;
 
178
}
 
179
 
 
180
static unsigned long pllc2_recalc(struct clk *clk)
 
181
{
 
182
        unsigned long mult = 1;
 
183
 
 
184
        pllc2_table_rebuild(clk);
 
185
 
 
186
        /*
 
187
         * If the PLL is off, mult == 1, clk->rate will be updated in
 
188
         * pllc2_enable().
 
189
         */
 
190
        if (__raw_readl(PLLC2CR) & (1 << 31))
 
191
                mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
 
192
 
 
193
        return clk->parent->rate * mult;
 
194
}
 
195
 
 
196
static long pllc2_round_rate(struct clk *clk, unsigned long rate)
 
197
{
 
198
        return clk_rate_table_round(clk, clk->freq_table, rate);
 
199
}
 
200
 
 
201
static int pllc2_enable(struct clk *clk)
 
202
{
 
203
        int i;
 
204
 
 
205
        __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
 
206
 
 
207
        for (i = 0; i < 100; i++)
 
208
                if (__raw_readl(PLLC2CR) & 0x80000000) {
 
209
                        clk->rate = pllc2_recalc(clk);
 
210
                        return 0;
 
211
                }
 
212
 
 
213
        pr_err("%s(): timeout!\n", __func__);
 
214
 
 
215
        return -ETIMEDOUT;
 
216
}
 
217
 
 
218
static void pllc2_disable(struct clk *clk)
 
219
{
 
220
        __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
 
221
}
 
222
 
 
223
static int pllc2_set_rate(struct clk *clk, unsigned long rate)
 
224
{
 
225
        unsigned long value;
 
226
        int idx;
 
227
 
 
228
        idx = clk_rate_table_find(clk, clk->freq_table, rate);
 
229
        if (idx < 0)
 
230
                return idx;
 
231
 
 
232
        if (rate == clk->parent->rate)
 
233
                return -EINVAL;
 
234
 
 
235
        value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
 
236
 
 
237
        __raw_writel(value | ((idx + 19) << 24), PLLC2CR);
 
238
 
 
239
        clk->rate = clk->freq_table[idx].frequency;
 
240
 
 
241
        return 0;
 
242
}
 
243
 
 
244
static int pllc2_set_parent(struct clk *clk, struct clk *parent)
 
245
{
 
246
        u32 value;
 
247
        int ret, i;
 
248
 
 
249
        if (!clk->parent_table || !clk->parent_num)
 
250
                return -EINVAL;
 
251
 
 
252
        /* Search the parent */
 
253
        for (i = 0; i < clk->parent_num; i++)
 
254
                if (clk->parent_table[i] == parent)
 
255
                        break;
 
256
 
 
257
        if (i == clk->parent_num)
 
258
                return -ENODEV;
 
259
 
 
260
        ret = clk_reparent(clk, parent);
 
261
        if (ret < 0)
 
262
                return ret;
 
263
 
 
264
        value = __raw_readl(PLLC2CR) & ~(3 << 6);
 
265
 
 
266
        __raw_writel(value | (i << 6), PLLC2CR);
 
267
 
 
268
        /* Rebiuld the frequency table */
 
269
        pllc2_table_rebuild(clk);
 
270
 
 
271
        return 0;
 
272
}
 
273
 
 
274
static struct clk_ops pllc2_clk_ops = {
 
275
        .recalc         = pllc2_recalc,
 
276
        .round_rate     = pllc2_round_rate,
 
277
        .set_rate       = pllc2_set_rate,
 
278
        .enable         = pllc2_enable,
 
279
        .disable        = pllc2_disable,
 
280
        .set_parent     = pllc2_set_parent,
 
281
};
 
282
 
 
283
struct clk sh7372_pllc2_clk = {
 
284
        .ops            = &pllc2_clk_ops,
 
285
        .parent         = &extal1_div2_clk,
 
286
        .freq_table     = pllc2_freq_table,
 
287
        .nr_freqs       = ARRAY_SIZE(pllc2_freq_table) - 1,
 
288
        .parent_table   = pllc2_parent,
 
289
        .parent_num     = ARRAY_SIZE(pllc2_parent),
 
290
};
 
291
 
 
292
/* External input clock (pin name: FSIACK/FSIBCK ) */
 
293
struct clk sh7372_fsiack_clk = {
 
294
};
 
295
 
 
296
struct clk sh7372_fsibck_clk = {
 
297
};
 
298
 
 
299
static struct clk *main_clks[] = {
 
300
        &sh7372_dv_clki_clk,
 
301
        &r_clk,
 
302
        &sh7372_extal1_clk,
 
303
        &sh7372_extal2_clk,
 
304
        &sh7372_dv_clki_div2_clk,
 
305
        &extal1_div2_clk,
 
306
        &extal2_div2_clk,
 
307
        &extal2_div4_clk,
 
308
        &pllc0_clk,
 
309
        &pllc1_clk,
 
310
        &pllc1_div2_clk,
 
311
        &sh7372_pllc2_clk,
 
312
        &sh7372_fsiack_clk,
 
313
        &sh7372_fsibck_clk,
 
314
};
 
315
 
 
316
static void div4_kick(struct clk *clk)
 
317
{
 
318
        unsigned long value;
 
319
 
 
320
        /* set KICK bit in FRQCRB to update hardware setting */
 
321
        value = __raw_readl(FRQCRB);
 
322
        value |= (1 << 31);
 
323
        __raw_writel(value, FRQCRB);
 
324
}
 
325
 
 
326
static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
 
327
                          24, 32, 36, 48, 0, 72, 96, 0 };
 
328
 
 
329
static struct clk_div_mult_table div4_div_mult_table = {
 
330
        .divisors = divisors,
 
331
        .nr_divisors = ARRAY_SIZE(divisors),
 
332
};
 
333
 
 
334
static struct clk_div4_table div4_table = {
 
335
        .div_mult_table = &div4_div_mult_table,
 
336
        .kick = div4_kick,
 
337
};
 
338
 
 
339
enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
 
340
       DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
 
341
       DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
 
342
       DIV4_DDRP, DIV4_NR };
 
343
 
 
344
#define DIV4(_reg, _bit, _mask, _flags) \
 
345
  SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
 
346
 
 
347
static struct clk div4_clks[DIV4_NR] = {
 
348
        [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
 
349
        [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
 
350
        [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
 
351
        [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
 
352
        [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
 
353
        [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
 
354
        [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
 
355
        [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
 
356
        [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
 
357
        [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
 
358
        [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
 
359
        [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
 
360
        [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
 
361
        [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
 
362
        [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
 
363
};
 
364
 
 
365
enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
 
366
       DIV6_SUB, DIV6_SPU,
 
367
       DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
 
368
       DIV6_NR };
 
369
 
 
370
static struct clk div6_clks[DIV6_NR] = {
 
371
        [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
 
372
        [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
 
373
        [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
 
374
        [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
 
375
        [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
 
376
        [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
 
377
        [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
 
378
        [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
 
379
        [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
 
380
        [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
 
381
        [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
 
382
};
 
383
 
 
384
enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
 
385
 
 
386
/* Indices are important - they are the actual src selecting values */
 
387
static struct clk *hdmi_parent[] = {
 
388
        [0] = &pllc1_div2_clk,
 
389
        [1] = &sh7372_pllc2_clk,
 
390
        [2] = &sh7372_dv_clki_clk,
 
391
        [3] = NULL,     /* pllc2_div4 not implemented yet */
 
392
};
 
393
 
 
394
static struct clk *fsiackcr_parent[] = {
 
395
        [0] = &pllc1_div2_clk,
 
396
        [1] = &sh7372_pllc2_clk,
 
397
        [2] = &sh7372_fsiack_clk, /* external input for FSI A */
 
398
        [3] = NULL,     /* setting prohibited */
 
399
};
 
400
 
 
401
static struct clk *fsibckcr_parent[] = {
 
402
        [0] = &pllc1_div2_clk,
 
403
        [1] = &sh7372_pllc2_clk,
 
404
        [2] = &sh7372_fsibck_clk, /* external input for FSI B */
 
405
        [3] = NULL,     /* setting prohibited */
 
406
};
 
407
 
 
408
static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
 
409
        [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
 
410
                                      hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
 
411
        [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
 
412
                                      fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
 
413
        [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
 
414
                                      fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
 
415
};
 
416
 
 
417
/* FSI DIV */
 
418
static unsigned long fsidiv_recalc(struct clk *clk)
 
419
{
 
420
        unsigned long value;
 
421
 
 
422
        value = __raw_readl(clk->mapping->base);
 
423
 
 
424
        if ((value & 0x3) != 0x3)
 
425
                return 0;
 
426
 
 
427
        value >>= 16;
 
428
        if (value < 2)
 
429
                return 0;
 
430
 
 
431
        return clk->parent->rate / value;
 
432
}
 
433
 
 
434
static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
 
435
{
 
436
        return clk_rate_div_range_round(clk, 2, 0xffff, rate);
 
437
}
 
438
 
 
439
static void fsidiv_disable(struct clk *clk)
 
440
{
 
441
        __raw_writel(0, clk->mapping->base);
 
442
}
 
443
 
 
444
static int fsidiv_enable(struct clk *clk)
 
445
{
 
446
        unsigned long value;
 
447
 
 
448
        value  = __raw_readl(clk->mapping->base) >> 16;
 
449
        if (value < 2)
 
450
                return -EIO;
 
451
 
 
452
        __raw_writel((value << 16) | 0x3, clk->mapping->base);
 
453
 
 
454
        return 0;
 
455
}
 
456
 
 
457
static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
 
458
{
 
459
        int idx;
 
460
 
 
461
        idx = (clk->parent->rate / rate) & 0xffff;
 
462
        if (idx < 2)
 
463
                return -EINVAL;
 
464
 
 
465
        __raw_writel(idx << 16, clk->mapping->base);
 
466
        return 0;
 
467
}
 
468
 
 
469
static struct clk_ops fsidiv_clk_ops = {
 
470
        .recalc         = fsidiv_recalc,
 
471
        .round_rate     = fsidiv_round_rate,
 
472
        .set_rate       = fsidiv_set_rate,
 
473
        .enable         = fsidiv_enable,
 
474
        .disable        = fsidiv_disable,
 
475
};
 
476
 
 
477
static struct clk_mapping sh7372_fsidiva_clk_mapping = {
 
478
        .phys   = FSIDIVA,
 
479
        .len    = 8,
 
480
};
 
481
 
 
482
struct clk sh7372_fsidiva_clk = {
 
483
        .ops            = &fsidiv_clk_ops,
 
484
        .parent         = &div6_reparent_clks[DIV6_FSIA], /* late install */
 
485
        .mapping        = &sh7372_fsidiva_clk_mapping,
 
486
};
 
487
 
 
488
static struct clk_mapping sh7372_fsidivb_clk_mapping = {
 
489
        .phys   = FSIDIVB,
 
490
        .len    = 8,
 
491
};
 
492
 
 
493
struct clk sh7372_fsidivb_clk = {
 
494
        .ops            = &fsidiv_clk_ops,
 
495
        .parent         = &div6_reparent_clks[DIV6_FSIB],  /* late install */
 
496
        .mapping        = &sh7372_fsidivb_clk_mapping,
 
497
};
 
498
 
 
499
static struct clk *late_main_clks[] = {
 
500
        &sh7372_fsidiva_clk,
 
501
        &sh7372_fsidivb_clk,
 
502
};
 
503
 
 
504
enum { MSTP001,
 
505
       MSTP131, MSTP130,
 
506
       MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
 
507
       MSTP118, MSTP117, MSTP116,
 
508
       MSTP106, MSTP101, MSTP100,
 
509
       MSTP223,
 
510
       MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
 
511
       MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
 
512
       MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
 
513
       MSTP_NR };
 
514
 
 
515
#define MSTP(_parent, _reg, _bit, _flags) \
 
516
  SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
 
517
 
 
518
static struct clk mstp_clks[MSTP_NR] = {
 
519
        [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
 
520
        [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
 
521
        [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
 
522
        [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
 
523
        [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
 
524
        [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
 
525
        [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
 
526
        [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
 
527
        [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
 
528
        [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
 
529
        [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
 
530
        [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
 
531
        [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
 
532
        [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
 
533
        [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
 
534
        [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
 
535
        [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
 
536
        [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
 
537
        [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
 
538
        [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
 
539
        [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
 
540
        [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
 
541
        [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
 
542
        [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
 
543
        [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
 
544
        [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
 
545
        [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
 
546
        [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
 
547
        [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
 
548
        [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
 
549
        [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
 
550
        [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
 
551
        [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
 
552
        [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
 
553
        [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
 
554
        [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
 
555
};
 
556
 
 
557
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 
558
#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
 
559
#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
 
560
 
 
561
static struct clk_lookup lookups[] = {
 
562
        /* main clocks */
 
563
        CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
 
564
        CLKDEV_CON_ID("r_clk", &r_clk),
 
565
        CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
 
566
        CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
 
567
        CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
 
568
        CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
 
569
        CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
 
570
        CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
 
571
        CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
 
572
        CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
 
573
        CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
 
574
 
 
575
        /* DIV4 clocks */
 
576
        CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
 
577
        CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
 
578
        CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
 
579
        CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
 
580
        CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
 
581
        CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
 
582
        CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
 
583
        CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
 
584
        CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
 
585
        CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
 
586
        CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
 
587
        CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
 
588
        CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
 
589
        CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
 
590
        CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
 
591
 
 
592
        /* DIV6 clocks */
 
593
        CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
 
594
        CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
 
595
        CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
 
596
        CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
 
597
        CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
 
598
        CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
 
599
        CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
 
600
        CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
 
601
        CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
 
602
        CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
 
603
        CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
 
604
        CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
 
605
        CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
 
606
 
 
607
        /* MSTP32 clocks */
 
608
        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
 
609
        CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
 
610
        CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
 
611
        CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
 
612
        CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
 
613
        CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
 
614
        CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
 
615
        CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
 
616
        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
 
617
        CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
 
618
        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
 
619
        CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
 
620
        CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
 
621
        CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
 
622
        CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
 
623
        CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
 
624
        CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
 
625
        CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
 
626
        CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
 
627
        CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
 
628
        CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
 
629
        CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
 
630
        CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
 
631
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
 
632
        CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
 
633
        CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
 
634
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
 
635
        CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
 
636
        CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
 
637
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
 
638
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
 
639
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
 
640
        CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
 
641
        CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
 
642
        CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
 
643
        CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
 
644
        CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
 
645
        CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
 
646
        CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
 
647
        CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
 
648
 
 
649
        CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
 
650
        CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
 
651
        CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
 
652
};
 
653
 
 
654
void __init sh7372_clock_init(void)
 
655
{
 
656
        int k, ret = 0;
 
657
 
 
658
        for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 
659
                ret = clk_register(main_clks[k]);
 
660
 
 
661
        if (!ret)
 
662
                ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
663
 
 
664
        if (!ret)
 
665
                ret = sh_clk_div6_register(div6_clks, DIV6_NR);
 
666
 
 
667
        if (!ret)
 
668
                ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
 
669
 
 
670
        if (!ret)
 
671
                ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
 
672
 
 
673
        for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
 
674
                ret = clk_register(late_main_clks[k]);
 
675
 
 
676
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
677
 
 
678
        if (!ret)
 
679
                clk_init();
 
680
        else
 
681
                panic("failed to setup sh7372 clocks\n");
 
682
 
 
683
}