Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-imx/clock-imx21.c
10817 views
1
/*
2
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3
* Copyright 2008 Juergen Beisert, [email protected]
4
* Copyright 2008 Martin Fuzzey, [email protected]
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
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., 51 Franklin Street, Fifth Floor, Boston,
18
* MA 02110-1301, USA.
19
*/
20
21
#include <linux/clk.h>
22
#include <linux/io.h>
23
#include <linux/module.h>
24
#include <linux/clkdev.h>
25
26
#include <mach/clock.h>
27
#include <mach/hardware.h>
28
#include <mach/common.h>
29
#include <asm/div64.h>
30
31
#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
32
33
/* Register offsets */
34
#define CCM_CSCR IO_ADDR_CCM(0x0)
35
#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
36
#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
37
#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
38
#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
39
#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
40
#define CCM_PCDR0 IO_ADDR_CCM(0x18)
41
#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
42
#define CCM_PCCR0 IO_ADDR_CCM(0x20)
43
#define CCM_PCCR1 IO_ADDR_CCM(0x24)
44
#define CCM_CCSR IO_ADDR_CCM(0x28)
45
#define CCM_PMCTL IO_ADDR_CCM(0x2c)
46
#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
47
#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
48
49
#define CCM_CSCR_PRESC_OFFSET 29
50
#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
51
52
#define CCM_CSCR_USB_OFFSET 26
53
#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
54
#define CCM_CSCR_SD_OFFSET 24
55
#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
56
#define CCM_CSCR_SPLLRES (1 << 22)
57
#define CCM_CSCR_MPLLRES (1 << 21)
58
#define CCM_CSCR_SSI2_OFFSET 20
59
#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
60
#define CCM_CSCR_SSI1_OFFSET 19
61
#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
62
#define CCM_CSCR_FIR_OFFSET 18
63
#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
64
#define CCM_CSCR_SP (1 << 17)
65
#define CCM_CSCR_MCU (1 << 16)
66
#define CCM_CSCR_BCLK_OFFSET 10
67
#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
68
#define CCM_CSCR_IPDIV_OFFSET 9
69
#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
70
71
#define CCM_CSCR_OSC26MDIV (1 << 4)
72
#define CCM_CSCR_OSC26M (1 << 3)
73
#define CCM_CSCR_FPM (1 << 2)
74
#define CCM_CSCR_SPEN (1 << 1)
75
#define CCM_CSCR_MPEN 1
76
77
#define CCM_MPCTL0_CPLM (1 << 31)
78
#define CCM_MPCTL0_PD_OFFSET 26
79
#define CCM_MPCTL0_PD_MASK (0xf << 26)
80
#define CCM_MPCTL0_MFD_OFFSET 16
81
#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
82
#define CCM_MPCTL0_MFI_OFFSET 10
83
#define CCM_MPCTL0_MFI_MASK (0xf << 10)
84
#define CCM_MPCTL0_MFN_OFFSET 0
85
#define CCM_MPCTL0_MFN_MASK 0x3ff
86
87
#define CCM_MPCTL1_LF (1 << 15)
88
#define CCM_MPCTL1_BRMO (1 << 6)
89
90
#define CCM_SPCTL0_CPLM (1 << 31)
91
#define CCM_SPCTL0_PD_OFFSET 26
92
#define CCM_SPCTL0_PD_MASK (0xf << 26)
93
#define CCM_SPCTL0_MFD_OFFSET 16
94
#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
95
#define CCM_SPCTL0_MFI_OFFSET 10
96
#define CCM_SPCTL0_MFI_MASK (0xf << 10)
97
#define CCM_SPCTL0_MFN_OFFSET 0
98
#define CCM_SPCTL0_MFN_MASK 0x3ff
99
100
#define CCM_SPCTL1_LF (1 << 15)
101
#define CCM_SPCTL1_BRMO (1 << 6)
102
103
#define CCM_OSC26MCTL_PEAK_OFFSET 16
104
#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
105
#define CCM_OSC26MCTL_AGC_OFFSET 8
106
#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
107
#define CCM_OSC26MCTL_ANATEST_OFFSET 0
108
#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
109
110
#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
111
#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
112
#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
113
#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
114
#define CCM_PCDR0_NFCDIV_OFFSET 12
115
#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
116
#define CCM_PCDR0_48MDIV_OFFSET 5
117
#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
118
#define CCM_PCDR0_FIRIDIV_OFFSET 0
119
#define CCM_PCDR0_FIRIDIV_MASK 0x1f
120
#define CCM_PCDR1_PERDIV4_OFFSET 24
121
#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
122
#define CCM_PCDR1_PERDIV3_OFFSET 16
123
#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
124
#define CCM_PCDR1_PERDIV2_OFFSET 8
125
#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
126
#define CCM_PCDR1_PERDIV1_OFFSET 0
127
#define CCM_PCDR1_PERDIV1_MASK 0x3f
128
129
#define CCM_PCCR_HCLK_CSI_OFFSET 31
130
#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
131
#define CCM_PCCR_HCLK_DMA_OFFSET 30
132
#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
133
#define CCM_PCCR_HCLK_BROM_OFFSET 28
134
#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
135
#define CCM_PCCR_HCLK_EMMA_OFFSET 27
136
#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
137
#define CCM_PCCR_HCLK_LCDC_OFFSET 26
138
#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
139
#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
140
#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
141
#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
142
#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
143
#define CCM_PCCR_HCLK_BMI_OFFSET 23
144
#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
145
#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
146
#define CCM_PCCR_PERCLK4_OFFSET 22
147
#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
148
#define CCM_PCCR_SLCDC_OFFSET 21
149
#define CCM_PCCR_SLCDC_REG CCM_PCCR0
150
#define CCM_PCCR_FIRI_BAUD_OFFSET 20
151
#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
152
#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
153
#define CCM_PCCR_NFC_OFFSET 19
154
#define CCM_PCCR_NFC_REG CCM_PCCR0
155
#define CCM_PCCR_LCDC_OFFSET 18
156
#define CCM_PCCR_LCDC_REG CCM_PCCR0
157
#define CCM_PCCR_SSI1_BAUD_OFFSET 17
158
#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
159
#define CCM_PCCR_SSI2_BAUD_OFFSET 16
160
#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
161
#define CCM_PCCR_EMMA_OFFSET 15
162
#define CCM_PCCR_EMMA_REG CCM_PCCR0
163
#define CCM_PCCR_USBOTG_OFFSET 14
164
#define CCM_PCCR_USBOTG_REG CCM_PCCR0
165
#define CCM_PCCR_DMA_OFFSET 13
166
#define CCM_PCCR_DMA_REG CCM_PCCR0
167
#define CCM_PCCR_I2C1_OFFSET 12
168
#define CCM_PCCR_I2C1_REG CCM_PCCR0
169
#define CCM_PCCR_GPIO_OFFSET 11
170
#define CCM_PCCR_GPIO_REG CCM_PCCR0
171
#define CCM_PCCR_SDHC2_OFFSET 10
172
#define CCM_PCCR_SDHC2_REG CCM_PCCR0
173
#define CCM_PCCR_SDHC1_OFFSET 9
174
#define CCM_PCCR_SDHC1_REG CCM_PCCR0
175
#define CCM_PCCR_FIRI_OFFSET 8
176
#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
177
#define CCM_PCCR_FIRI_REG CCM_PCCR0
178
#define CCM_PCCR_SSI2_IPG_OFFSET 7
179
#define CCM_PCCR_SSI2_REG CCM_PCCR0
180
#define CCM_PCCR_SSI1_IPG_OFFSET 6
181
#define CCM_PCCR_SSI1_REG CCM_PCCR0
182
#define CCM_PCCR_CSPI2_OFFSET 5
183
#define CCM_PCCR_CSPI2_REG CCM_PCCR0
184
#define CCM_PCCR_CSPI1_OFFSET 4
185
#define CCM_PCCR_CSPI1_REG CCM_PCCR0
186
#define CCM_PCCR_UART4_OFFSET 3
187
#define CCM_PCCR_UART4_REG CCM_PCCR0
188
#define CCM_PCCR_UART3_OFFSET 2
189
#define CCM_PCCR_UART3_REG CCM_PCCR0
190
#define CCM_PCCR_UART2_OFFSET 1
191
#define CCM_PCCR_UART2_REG CCM_PCCR0
192
#define CCM_PCCR_UART1_OFFSET 0
193
#define CCM_PCCR_UART1_REG CCM_PCCR0
194
195
#define CCM_PCCR_OWIRE_OFFSET 31
196
#define CCM_PCCR_OWIRE_REG CCM_PCCR1
197
#define CCM_PCCR_KPP_OFFSET 30
198
#define CCM_PCCR_KPP_REG CCM_PCCR1
199
#define CCM_PCCR_RTC_OFFSET 29
200
#define CCM_PCCR_RTC_REG CCM_PCCR1
201
#define CCM_PCCR_PWM_OFFSET 28
202
#define CCM_PCCR_PWM_REG CCM_PCCR1
203
#define CCM_PCCR_GPT3_OFFSET 27
204
#define CCM_PCCR_GPT3_REG CCM_PCCR1
205
#define CCM_PCCR_GPT2_OFFSET 26
206
#define CCM_PCCR_GPT2_REG CCM_PCCR1
207
#define CCM_PCCR_GPT1_OFFSET 25
208
#define CCM_PCCR_GPT1_REG CCM_PCCR1
209
#define CCM_PCCR_WDT_OFFSET 24
210
#define CCM_PCCR_WDT_REG CCM_PCCR1
211
#define CCM_PCCR_CSPI3_OFFSET 23
212
#define CCM_PCCR_CSPI3_REG CCM_PCCR1
213
214
#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
215
#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
216
#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
217
#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
218
#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
219
#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
220
#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
221
#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
222
#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
223
#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
224
#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
225
#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
226
#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
227
#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
228
#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
229
#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
230
#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
231
#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
232
#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
233
#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
234
#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
235
#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
236
#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
237
#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
238
#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
239
#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
240
#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
241
#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
242
#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
243
#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
244
#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
245
#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
246
#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
247
#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
248
#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
249
#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
250
#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
251
252
#define CCM_CCSR_32KSR (1 << 15)
253
254
#define CCM_CCSR_CLKMODE1 (1 << 9)
255
#define CCM_CCSR_CLKMODE0 (1 << 8)
256
257
#define CCM_CCSR_CLKOSEL_OFFSET 0
258
#define CCM_CCSR_CLKOSEL_MASK 0x1f
259
260
#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
261
#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
262
263
static int _clk_enable(struct clk *clk)
264
{
265
u32 reg;
266
267
reg = __raw_readl(clk->enable_reg);
268
reg |= 1 << clk->enable_shift;
269
__raw_writel(reg, clk->enable_reg);
270
return 0;
271
}
272
273
static void _clk_disable(struct clk *clk)
274
{
275
u32 reg;
276
277
reg = __raw_readl(clk->enable_reg);
278
reg &= ~(1 << clk->enable_shift);
279
__raw_writel(reg, clk->enable_reg);
280
}
281
282
static unsigned long _clk_generic_round_rate(struct clk *clk,
283
unsigned long rate,
284
u32 max_divisor)
285
{
286
u32 div;
287
unsigned long parent_rate;
288
289
parent_rate = clk_get_rate(clk->parent);
290
291
div = parent_rate / rate;
292
if (parent_rate % rate)
293
div++;
294
295
if (div > max_divisor)
296
div = max_divisor;
297
298
return parent_rate / div;
299
}
300
301
static int _clk_spll_enable(struct clk *clk)
302
{
303
u32 reg;
304
305
reg = __raw_readl(CCM_CSCR);
306
reg |= CCM_CSCR_SPEN;
307
__raw_writel(reg, CCM_CSCR);
308
309
while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
310
;
311
return 0;
312
}
313
314
static void _clk_spll_disable(struct clk *clk)
315
{
316
u32 reg;
317
318
reg = __raw_readl(CCM_CSCR);
319
reg &= ~CCM_CSCR_SPEN;
320
__raw_writel(reg, CCM_CSCR);
321
}
322
323
324
#define CSCR() (__raw_readl(CCM_CSCR))
325
#define PCDR0() (__raw_readl(CCM_PCDR0))
326
#define PCDR1() (__raw_readl(CCM_PCDR1))
327
328
static unsigned long _clk_perclkx_round_rate(struct clk *clk,
329
unsigned long rate)
330
{
331
return _clk_generic_round_rate(clk, rate, 64);
332
}
333
334
static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
335
{
336
u32 reg;
337
u32 div;
338
unsigned long parent_rate;
339
340
parent_rate = clk_get_rate(clk->parent);
341
342
if (clk->id < 0 || clk->id > 3)
343
return -EINVAL;
344
345
div = parent_rate / rate;
346
if (div > 64 || div < 1 || ((parent_rate / div) != rate))
347
return -EINVAL;
348
div--;
349
350
reg =
351
__raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
352
(clk->id << 3));
353
reg |= div << (clk->id << 3);
354
__raw_writel(reg, CCM_PCDR1);
355
356
return 0;
357
}
358
359
static unsigned long _clk_usb_recalc(struct clk *clk)
360
{
361
unsigned long usb_pdf;
362
unsigned long parent_rate;
363
364
parent_rate = clk_get_rate(clk->parent);
365
366
usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
367
368
return parent_rate / (usb_pdf + 1U);
369
}
370
371
static unsigned long _clk_usb_round_rate(struct clk *clk,
372
unsigned long rate)
373
{
374
return _clk_generic_round_rate(clk, rate, 8);
375
}
376
377
static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
378
{
379
u32 reg;
380
u32 div;
381
unsigned long parent_rate;
382
383
parent_rate = clk_get_rate(clk->parent);
384
385
div = parent_rate / rate;
386
if (div > 8 || div < 1 || ((parent_rate / div) != rate))
387
return -EINVAL;
388
div--;
389
390
reg = CSCR() & ~CCM_CSCR_USB_MASK;
391
reg |= div << CCM_CSCR_USB_OFFSET;
392
__raw_writel(reg, CCM_CSCR);
393
394
return 0;
395
}
396
397
static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
398
{
399
unsigned long parent_rate;
400
401
parent_rate = clk_get_rate(clk->parent);
402
403
pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
404
405
return 2UL * parent_rate / pdf;
406
}
407
408
static unsigned long _clk_ssi1_recalc(struct clk *clk)
409
{
410
return _clk_ssix_recalc(clk,
411
(PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
412
>> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
413
}
414
415
static unsigned long _clk_ssi2_recalc(struct clk *clk)
416
{
417
return _clk_ssix_recalc(clk,
418
(PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
419
CCM_PCDR0_SSI2BAUDDIV_OFFSET);
420
}
421
422
static unsigned long _clk_nfc_recalc(struct clk *clk)
423
{
424
unsigned long nfc_pdf;
425
unsigned long parent_rate;
426
427
parent_rate = clk_get_rate(clk->parent);
428
429
nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
430
>> CCM_PCDR0_NFCDIV_OFFSET;
431
432
return parent_rate / (nfc_pdf + 1);
433
}
434
435
static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
436
{
437
return clk->parent->round_rate(clk->parent, rate);
438
}
439
440
static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
441
{
442
return clk->parent->set_rate(clk->parent, rate);
443
}
444
445
static unsigned long external_high_reference; /* in Hz */
446
447
static unsigned long get_high_reference_clock_rate(struct clk *clk)
448
{
449
return external_high_reference;
450
}
451
452
/*
453
* the high frequency external clock reference
454
* Default case is 26MHz.
455
*/
456
static struct clk ckih_clk = {
457
.get_rate = get_high_reference_clock_rate,
458
};
459
460
static unsigned long external_low_reference; /* in Hz */
461
462
static unsigned long get_low_reference_clock_rate(struct clk *clk)
463
{
464
return external_low_reference;
465
}
466
467
/*
468
* the low frequency external clock reference
469
* Default case is 32.768kHz.
470
*/
471
static struct clk ckil_clk = {
472
.get_rate = get_low_reference_clock_rate,
473
};
474
475
476
static unsigned long _clk_fpm_recalc(struct clk *clk)
477
{
478
return clk_get_rate(clk->parent) * 512;
479
}
480
481
/* Output of frequency pre multiplier */
482
static struct clk fpm_clk = {
483
.parent = &ckil_clk,
484
.get_rate = _clk_fpm_recalc,
485
};
486
487
static unsigned long get_mpll_clk(struct clk *clk)
488
{
489
uint32_t reg;
490
unsigned long ref_clk;
491
unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
492
unsigned long long temp;
493
494
ref_clk = clk_get_rate(clk->parent);
495
496
reg = __raw_readl(CCM_MPCTL0);
497
pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
498
mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
499
mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
500
mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
501
502
mfi = (mfi <= 5) ? 5 : mfi;
503
temp = 2LL * ref_clk * mfn;
504
do_div(temp, mfd + 1);
505
temp = 2LL * ref_clk * mfi + temp;
506
do_div(temp, pdf + 1);
507
508
return (unsigned long)temp;
509
}
510
511
static struct clk mpll_clk = {
512
.parent = &ckih_clk,
513
.get_rate = get_mpll_clk,
514
};
515
516
static unsigned long _clk_fclk_get_rate(struct clk *clk)
517
{
518
unsigned long parent_rate;
519
u32 div;
520
521
div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
522
parent_rate = clk_get_rate(clk->parent);
523
524
return parent_rate / (div+1);
525
}
526
527
static struct clk fclk_clk = {
528
.parent = &mpll_clk,
529
.get_rate = _clk_fclk_get_rate
530
};
531
532
static unsigned long get_spll_clk(struct clk *clk)
533
{
534
uint32_t reg;
535
unsigned long ref_clk;
536
unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
537
unsigned long long temp;
538
539
ref_clk = clk_get_rate(clk->parent);
540
541
reg = __raw_readl(CCM_SPCTL0);
542
pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
543
mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
544
mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
545
mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
546
547
mfi = (mfi <= 5) ? 5 : mfi;
548
temp = 2LL * ref_clk * mfn;
549
do_div(temp, mfd + 1);
550
temp = 2LL * ref_clk * mfi + temp;
551
do_div(temp, pdf + 1);
552
553
return (unsigned long)temp;
554
}
555
556
static struct clk spll_clk = {
557
.parent = &ckih_clk,
558
.get_rate = get_spll_clk,
559
.enable = _clk_spll_enable,
560
.disable = _clk_spll_disable,
561
};
562
563
static unsigned long get_hclk_clk(struct clk *clk)
564
{
565
unsigned long rate;
566
unsigned long bclk_pdf;
567
568
bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
569
>> CCM_CSCR_BCLK_OFFSET;
570
571
rate = clk_get_rate(clk->parent);
572
return rate / (bclk_pdf + 1);
573
}
574
575
static struct clk hclk_clk = {
576
.parent = &fclk_clk,
577
.get_rate = get_hclk_clk,
578
};
579
580
static unsigned long get_ipg_clk(struct clk *clk)
581
{
582
unsigned long rate;
583
unsigned long ipg_pdf;
584
585
ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
586
587
rate = clk_get_rate(clk->parent);
588
return rate / (ipg_pdf + 1);
589
}
590
591
static struct clk ipg_clk = {
592
.parent = &hclk_clk,
593
.get_rate = get_ipg_clk,
594
};
595
596
static unsigned long _clk_perclkx_recalc(struct clk *clk)
597
{
598
unsigned long perclk_pdf;
599
unsigned long parent_rate;
600
601
parent_rate = clk_get_rate(clk->parent);
602
603
if (clk->id < 0 || clk->id > 3)
604
return 0;
605
606
perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
607
608
return parent_rate / (perclk_pdf + 1);
609
}
610
611
static struct clk per_clk[] = {
612
{
613
.id = 0,
614
.parent = &mpll_clk,
615
.get_rate = _clk_perclkx_recalc,
616
}, {
617
.id = 1,
618
.parent = &mpll_clk,
619
.get_rate = _clk_perclkx_recalc,
620
}, {
621
.id = 2,
622
.parent = &mpll_clk,
623
.round_rate = _clk_perclkx_round_rate,
624
.set_rate = _clk_perclkx_set_rate,
625
.get_rate = _clk_perclkx_recalc,
626
/* Enable/Disable done via lcd_clkc[1] */
627
}, {
628
.id = 3,
629
.parent = &mpll_clk,
630
.round_rate = _clk_perclkx_round_rate,
631
.set_rate = _clk_perclkx_set_rate,
632
.get_rate = _clk_perclkx_recalc,
633
/* Enable/Disable done via csi_clk[1] */
634
},
635
};
636
637
static struct clk uart_ipg_clk[];
638
639
static struct clk uart_clk[] = {
640
{
641
.id = 0,
642
.parent = &per_clk[0],
643
.secondary = &uart_ipg_clk[0],
644
}, {
645
.id = 1,
646
.parent = &per_clk[0],
647
.secondary = &uart_ipg_clk[1],
648
}, {
649
.id = 2,
650
.parent = &per_clk[0],
651
.secondary = &uart_ipg_clk[2],
652
}, {
653
.id = 3,
654
.parent = &per_clk[0],
655
.secondary = &uart_ipg_clk[3],
656
},
657
};
658
659
static struct clk uart_ipg_clk[] = {
660
{
661
.id = 0,
662
.parent = &ipg_clk,
663
.enable = _clk_enable,
664
.enable_reg = CCM_PCCR_UART1_REG,
665
.enable_shift = CCM_PCCR_UART1_OFFSET,
666
.disable = _clk_disable,
667
}, {
668
.id = 1,
669
.parent = &ipg_clk,
670
.enable = _clk_enable,
671
.enable_reg = CCM_PCCR_UART2_REG,
672
.enable_shift = CCM_PCCR_UART2_OFFSET,
673
.disable = _clk_disable,
674
}, {
675
.id = 2,
676
.parent = &ipg_clk,
677
.enable = _clk_enable,
678
.enable_reg = CCM_PCCR_UART3_REG,
679
.enable_shift = CCM_PCCR_UART3_OFFSET,
680
.disable = _clk_disable,
681
}, {
682
.id = 3,
683
.parent = &ipg_clk,
684
.enable = _clk_enable,
685
.enable_reg = CCM_PCCR_UART4_REG,
686
.enable_shift = CCM_PCCR_UART4_OFFSET,
687
.disable = _clk_disable,
688
},
689
};
690
691
static struct clk gpt_ipg_clk[];
692
693
static struct clk gpt_clk[] = {
694
{
695
.id = 0,
696
.parent = &per_clk[0],
697
.secondary = &gpt_ipg_clk[0],
698
}, {
699
.id = 1,
700
.parent = &per_clk[0],
701
.secondary = &gpt_ipg_clk[1],
702
}, {
703
.id = 2,
704
.parent = &per_clk[0],
705
.secondary = &gpt_ipg_clk[2],
706
},
707
};
708
709
static struct clk gpt_ipg_clk[] = {
710
{
711
.id = 0,
712
.parent = &ipg_clk,
713
.enable = _clk_enable,
714
.enable_reg = CCM_PCCR_GPT1_REG,
715
.enable_shift = CCM_PCCR_GPT1_OFFSET,
716
.disable = _clk_disable,
717
}, {
718
.id = 1,
719
.parent = &ipg_clk,
720
.enable = _clk_enable,
721
.enable_reg = CCM_PCCR_GPT2_REG,
722
.enable_shift = CCM_PCCR_GPT2_OFFSET,
723
.disable = _clk_disable,
724
}, {
725
.id = 2,
726
.parent = &ipg_clk,
727
.enable = _clk_enable,
728
.enable_reg = CCM_PCCR_GPT3_REG,
729
.enable_shift = CCM_PCCR_GPT3_OFFSET,
730
.disable = _clk_disable,
731
},
732
};
733
734
static struct clk pwm_clk[] = {
735
{
736
.parent = &per_clk[0],
737
.secondary = &pwm_clk[1],
738
}, {
739
.parent = &ipg_clk,
740
.enable = _clk_enable,
741
.enable_reg = CCM_PCCR_PWM_REG,
742
.enable_shift = CCM_PCCR_PWM_OFFSET,
743
.disable = _clk_disable,
744
},
745
};
746
747
static struct clk sdhc_ipg_clk[];
748
749
static struct clk sdhc_clk[] = {
750
{
751
.id = 0,
752
.parent = &per_clk[1],
753
.secondary = &sdhc_ipg_clk[0],
754
}, {
755
.id = 1,
756
.parent = &per_clk[1],
757
.secondary = &sdhc_ipg_clk[1],
758
},
759
};
760
761
static struct clk sdhc_ipg_clk[] = {
762
{
763
.id = 0,
764
.parent = &ipg_clk,
765
.enable = _clk_enable,
766
.enable_reg = CCM_PCCR_SDHC1_REG,
767
.enable_shift = CCM_PCCR_SDHC1_OFFSET,
768
.disable = _clk_disable,
769
}, {
770
.id = 1,
771
.parent = &ipg_clk,
772
.enable = _clk_enable,
773
.enable_reg = CCM_PCCR_SDHC2_REG,
774
.enable_shift = CCM_PCCR_SDHC2_OFFSET,
775
.disable = _clk_disable,
776
},
777
};
778
779
static struct clk cspi_ipg_clk[];
780
781
static struct clk cspi_clk[] = {
782
{
783
.id = 0,
784
.parent = &per_clk[1],
785
.secondary = &cspi_ipg_clk[0],
786
}, {
787
.id = 1,
788
.parent = &per_clk[1],
789
.secondary = &cspi_ipg_clk[1],
790
}, {
791
.id = 2,
792
.parent = &per_clk[1],
793
.secondary = &cspi_ipg_clk[2],
794
},
795
};
796
797
static struct clk cspi_ipg_clk[] = {
798
{
799
.id = 0,
800
.parent = &ipg_clk,
801
.enable = _clk_enable,
802
.enable_reg = CCM_PCCR_CSPI1_REG,
803
.enable_shift = CCM_PCCR_CSPI1_OFFSET,
804
.disable = _clk_disable,
805
}, {
806
.id = 1,
807
.parent = &ipg_clk,
808
.enable = _clk_enable,
809
.enable_reg = CCM_PCCR_CSPI2_REG,
810
.enable_shift = CCM_PCCR_CSPI2_OFFSET,
811
.disable = _clk_disable,
812
}, {
813
.id = 3,
814
.parent = &ipg_clk,
815
.enable = _clk_enable,
816
.enable_reg = CCM_PCCR_CSPI3_REG,
817
.enable_shift = CCM_PCCR_CSPI3_OFFSET,
818
.disable = _clk_disable,
819
},
820
};
821
822
static struct clk lcdc_clk[] = {
823
{
824
.parent = &per_clk[2],
825
.secondary = &lcdc_clk[1],
826
.round_rate = _clk_parent_round_rate,
827
.set_rate = _clk_parent_set_rate,
828
}, {
829
.parent = &ipg_clk,
830
.secondary = &lcdc_clk[2],
831
.enable = _clk_enable,
832
.enable_reg = CCM_PCCR_LCDC_REG,
833
.enable_shift = CCM_PCCR_LCDC_OFFSET,
834
.disable = _clk_disable,
835
}, {
836
.parent = &hclk_clk,
837
.enable = _clk_enable,
838
.enable_reg = CCM_PCCR_HCLK_LCDC_REG,
839
.enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
840
.disable = _clk_disable,
841
},
842
};
843
844
static struct clk csi_clk[] = {
845
{
846
.parent = &per_clk[3],
847
.secondary = &csi_clk[1],
848
.round_rate = _clk_parent_round_rate,
849
.set_rate = _clk_parent_set_rate,
850
}, {
851
.parent = &hclk_clk,
852
.enable = _clk_enable,
853
.enable_reg = CCM_PCCR_HCLK_CSI_REG,
854
.enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
855
.disable = _clk_disable,
856
},
857
};
858
859
static struct clk usb_clk[] = {
860
{
861
.parent = &spll_clk,
862
.secondary = &usb_clk[1],
863
.get_rate = _clk_usb_recalc,
864
.enable = _clk_enable,
865
.enable_reg = CCM_PCCR_USBOTG_REG,
866
.enable_shift = CCM_PCCR_USBOTG_OFFSET,
867
.disable = _clk_disable,
868
.round_rate = _clk_usb_round_rate,
869
.set_rate = _clk_usb_set_rate,
870
}, {
871
.parent = &hclk_clk,
872
.enable = _clk_enable,
873
.enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
874
.enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
875
.disable = _clk_disable,
876
}
877
};
878
879
static struct clk ssi_ipg_clk[];
880
881
static struct clk ssi_clk[] = {
882
{
883
.id = 0,
884
.parent = &mpll_clk,
885
.secondary = &ssi_ipg_clk[0],
886
.get_rate = _clk_ssi1_recalc,
887
.enable = _clk_enable,
888
.enable_reg = CCM_PCCR_SSI1_BAUD_REG,
889
.enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
890
.disable = _clk_disable,
891
}, {
892
.id = 1,
893
.parent = &mpll_clk,
894
.secondary = &ssi_ipg_clk[1],
895
.get_rate = _clk_ssi2_recalc,
896
.enable = _clk_enable,
897
.enable_reg = CCM_PCCR_SSI2_BAUD_REG,
898
.enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
899
.disable = _clk_disable,
900
},
901
};
902
903
static struct clk ssi_ipg_clk[] = {
904
{
905
.id = 0,
906
.parent = &ipg_clk,
907
.enable = _clk_enable,
908
.enable_reg = CCM_PCCR_SSI1_REG,
909
.enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
910
.disable = _clk_disable,
911
}, {
912
.id = 1,
913
.parent = &ipg_clk,
914
.enable = _clk_enable,
915
.enable_reg = CCM_PCCR_SSI2_REG,
916
.enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
917
.disable = _clk_disable,
918
},
919
};
920
921
922
static struct clk nfc_clk = {
923
.parent = &fclk_clk,
924
.get_rate = _clk_nfc_recalc,
925
.enable = _clk_enable,
926
.enable_reg = CCM_PCCR_NFC_REG,
927
.enable_shift = CCM_PCCR_NFC_OFFSET,
928
.disable = _clk_disable,
929
};
930
931
static struct clk dma_clk[] = {
932
{
933
.parent = &hclk_clk,
934
.enable = _clk_enable,
935
.enable_reg = CCM_PCCR_DMA_REG,
936
.enable_shift = CCM_PCCR_DMA_OFFSET,
937
.disable = _clk_disable,
938
.secondary = &dma_clk[1],
939
}, {
940
.enable = _clk_enable,
941
.enable_reg = CCM_PCCR_HCLK_DMA_REG,
942
.enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
943
.disable = _clk_disable,
944
},
945
};
946
947
static struct clk brom_clk = {
948
.parent = &hclk_clk,
949
.enable = _clk_enable,
950
.enable_reg = CCM_PCCR_HCLK_BROM_REG,
951
.enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
952
.disable = _clk_disable,
953
};
954
955
static struct clk emma_clk[] = {
956
{
957
.parent = &hclk_clk,
958
.enable = _clk_enable,
959
.enable_reg = CCM_PCCR_EMMA_REG,
960
.enable_shift = CCM_PCCR_EMMA_OFFSET,
961
.disable = _clk_disable,
962
.secondary = &emma_clk[1],
963
}, {
964
.enable = _clk_enable,
965
.enable_reg = CCM_PCCR_HCLK_EMMA_REG,
966
.enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
967
.disable = _clk_disable,
968
}
969
};
970
971
static struct clk slcdc_clk[] = {
972
{
973
.parent = &hclk_clk,
974
.enable = _clk_enable,
975
.enable_reg = CCM_PCCR_SLCDC_REG,
976
.enable_shift = CCM_PCCR_SLCDC_OFFSET,
977
.disable = _clk_disable,
978
.secondary = &slcdc_clk[1],
979
}, {
980
.enable = _clk_enable,
981
.enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
982
.enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
983
.disable = _clk_disable,
984
}
985
};
986
987
static struct clk wdog_clk = {
988
.parent = &ipg_clk,
989
.enable = _clk_enable,
990
.enable_reg = CCM_PCCR_WDT_REG,
991
.enable_shift = CCM_PCCR_WDT_OFFSET,
992
.disable = _clk_disable,
993
};
994
995
static struct clk gpio_clk = {
996
.parent = &ipg_clk,
997
.enable = _clk_enable,
998
.enable_reg = CCM_PCCR_GPIO_REG,
999
.enable_shift = CCM_PCCR_GPIO_OFFSET,
1000
.disable = _clk_disable,
1001
};
1002
1003
static struct clk i2c_clk = {
1004
.id = 0,
1005
.parent = &ipg_clk,
1006
.enable = _clk_enable,
1007
.enable_reg = CCM_PCCR_I2C1_REG,
1008
.enable_shift = CCM_PCCR_I2C1_OFFSET,
1009
.disable = _clk_disable,
1010
};
1011
1012
static struct clk kpp_clk = {
1013
.parent = &ipg_clk,
1014
.enable = _clk_enable,
1015
.enable_reg = CCM_PCCR_KPP_REG,
1016
.enable_shift = CCM_PCCR_KPP_OFFSET,
1017
.disable = _clk_disable,
1018
};
1019
1020
static struct clk owire_clk = {
1021
.parent = &ipg_clk,
1022
.enable = _clk_enable,
1023
.enable_reg = CCM_PCCR_OWIRE_REG,
1024
.enable_shift = CCM_PCCR_OWIRE_OFFSET,
1025
.disable = _clk_disable,
1026
};
1027
1028
static struct clk rtc_clk = {
1029
.parent = &ipg_clk,
1030
.enable = _clk_enable,
1031
.enable_reg = CCM_PCCR_RTC_REG,
1032
.enable_shift = CCM_PCCR_RTC_OFFSET,
1033
.disable = _clk_disable,
1034
};
1035
1036
static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1037
{
1038
return _clk_generic_round_rate(clk, rate, 8);
1039
}
1040
1041
static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1042
{
1043
u32 reg;
1044
u32 div;
1045
unsigned long parent_rate;
1046
1047
parent_rate = clk_get_rate(clk->parent);
1048
1049
div = parent_rate / rate;
1050
1051
if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1052
return -EINVAL;
1053
div--;
1054
1055
reg = __raw_readl(CCM_PCDR0);
1056
1057
if (clk->parent == &usb_clk[0]) {
1058
reg &= ~CCM_PCDR0_48MDIV_MASK;
1059
reg |= div << CCM_PCDR0_48MDIV_OFFSET;
1060
}
1061
__raw_writel(reg, CCM_PCDR0);
1062
1063
return 0;
1064
}
1065
1066
static unsigned long _clk_clko_recalc(struct clk *clk)
1067
{
1068
u32 div = 0;
1069
unsigned long parent_rate;
1070
1071
parent_rate = clk_get_rate(clk->parent);
1072
1073
if (clk->parent == &usb_clk[0]) /* 48M */
1074
div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
1075
>> CCM_PCDR0_48MDIV_OFFSET;
1076
div++;
1077
1078
return parent_rate / div;
1079
}
1080
1081
static struct clk clko_clk;
1082
1083
static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1084
{
1085
u32 reg;
1086
1087
reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1088
1089
if (parent == &ckil_clk)
1090
reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1091
else if (parent == &fpm_clk)
1092
reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
1093
else if (parent == &ckih_clk)
1094
reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1095
else if (parent == mpll_clk.parent)
1096
reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1097
else if (parent == spll_clk.parent)
1098
reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1099
else if (parent == &mpll_clk)
1100
reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1101
else if (parent == &spll_clk)
1102
reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1103
else if (parent == &fclk_clk)
1104
reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1105
else if (parent == &hclk_clk)
1106
reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1107
else if (parent == &ipg_clk)
1108
reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1109
else if (parent == &per_clk[0])
1110
reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1111
else if (parent == &per_clk[1])
1112
reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1113
else if (parent == &per_clk[2])
1114
reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1115
else if (parent == &per_clk[3])
1116
reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1117
else if (parent == &ssi_clk[0])
1118
reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1119
else if (parent == &ssi_clk[1])
1120
reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1121
else if (parent == &nfc_clk)
1122
reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1123
else if (parent == &usb_clk[0])
1124
reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
1125
else if (parent == &clko_clk)
1126
reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1127
else
1128
return -EINVAL;
1129
1130
__raw_writel(reg, CCM_CCSR);
1131
1132
return 0;
1133
}
1134
1135
static struct clk clko_clk = {
1136
.get_rate = _clk_clko_recalc,
1137
.set_rate = _clk_clko_set_rate,
1138
.round_rate = _clk_clko_round_rate,
1139
.set_parent = _clk_clko_set_parent,
1140
};
1141
1142
1143
#define _REGISTER_CLOCK(d, n, c) \
1144
{ \
1145
.dev_id = d, \
1146
.con_id = n, \
1147
.clk = &c, \
1148
},
1149
static struct clk_lookup lookups[] = {
1150
/* It's unlikely that any driver wants one of them directly:
1151
_REGISTER_CLOCK(NULL, "ckih", ckih_clk)
1152
_REGISTER_CLOCK(NULL, "ckil", ckil_clk)
1153
_REGISTER_CLOCK(NULL, "fpm", fpm_clk)
1154
_REGISTER_CLOCK(NULL, "mpll", mpll_clk)
1155
_REGISTER_CLOCK(NULL, "spll", spll_clk)
1156
_REGISTER_CLOCK(NULL, "fclk", fclk_clk)
1157
_REGISTER_CLOCK(NULL, "hclk", hclk_clk)
1158
_REGISTER_CLOCK(NULL, "ipg", ipg_clk)
1159
*/
1160
_REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
1161
_REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
1162
_REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
1163
_REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
1164
_REGISTER_CLOCK(NULL, "clko", clko_clk)
1165
_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
1166
_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
1167
_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
1168
_REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
1169
_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
1170
_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
1171
_REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
1172
_REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
1173
_REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
1174
_REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
1175
_REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
1176
_REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
1177
_REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
1178
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
1179
_REGISTER_CLOCK(NULL, "csi", csi_clk[0])
1180
_REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
1181
_REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
1182
_REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
1183
_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
1184
_REGISTER_CLOCK(NULL, "dma", dma_clk[0])
1185
_REGISTER_CLOCK(NULL, "brom", brom_clk)
1186
_REGISTER_CLOCK(NULL, "emma", emma_clk[0])
1187
_REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
1188
_REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
1189
_REGISTER_CLOCK(NULL, "gpio", gpio_clk)
1190
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
1191
_REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
1192
_REGISTER_CLOCK(NULL, "owire", owire_clk)
1193
_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
1194
};
1195
1196
/*
1197
* must be called very early to get information about the
1198
* available clock rate when the timer framework starts
1199
*/
1200
int __init mx21_clocks_init(unsigned long lref, unsigned long href)
1201
{
1202
u32 cscr;
1203
1204
external_low_reference = lref;
1205
external_high_reference = href;
1206
1207
/* detect clock reference for both system PLL */
1208
cscr = CSCR();
1209
if (cscr & CCM_CSCR_MCU)
1210
mpll_clk.parent = &ckih_clk;
1211
else
1212
mpll_clk.parent = &fpm_clk;
1213
1214
if (cscr & CCM_CSCR_SP)
1215
spll_clk.parent = &ckih_clk;
1216
else
1217
spll_clk.parent = &fpm_clk;
1218
1219
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
1220
1221
/* Turn off all clock gates */
1222
__raw_writel(0, CCM_PCCR0);
1223
__raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
1224
1225
/* This turns of the serial PLL as well */
1226
spll_clk.disable(&spll_clk);
1227
1228
/* This will propagate to all children and init all the clock rates. */
1229
clk_enable(&per_clk[0]);
1230
clk_enable(&gpio_clk);
1231
1232
#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
1233
clk_enable(&uart_clk[0]);
1234
#endif
1235
1236
mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
1237
MX21_INT_GPT1);
1238
return 0;
1239
}
1240
1241