Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
sh
kernel
cpu
sh4a
clock-sh7723.c
Go to the documentation of this file.
1
/*
2
* arch/sh/kernel/cpu/sh4a/clock-sh7723.c
3
*
4
* SH7723 clock framework support
5
*
6
* Copyright (C) 2009 Magnus Damm
7
*
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
*/
21
#include <
linux/init.h
>
22
#include <linux/kernel.h>
23
#include <
linux/io.h
>
24
#include <
linux/clk.h
>
25
#include <
linux/clkdev.h
>
26
#include <
linux/sh_clk.h
>
27
#include <asm/clock.h>
28
#include <
cpu/sh7723.h
>
29
30
/* SH7723 registers */
31
#define FRQCR 0xa4150000
32
#define VCLKCR 0xa4150004
33
#define SCLKACR 0xa4150008
34
#define SCLKBCR 0xa415000c
35
#define IRDACLKCR 0xa4150018
36
#define PLLCR 0xa4150024
37
#define MSTPCR0 0xa4150030
38
#define MSTPCR1 0xa4150034
39
#define MSTPCR2 0xa4150038
40
#define DLLFRQ 0xa4150050
41
42
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
43
static
struct
clk
r_clk = {
44
.rate = 32768,
45
};
46
47
/*
48
* Default rate for the root input clock, reset this with clk_set_rate()
49
* from the platform code.
50
*/
51
struct
clk
extal_clk
= {
52
.rate = 33333333,
53
};
54
55
/* The dll multiplies the 32khz r_clk, may be used instead of extal */
56
static
unsigned
long
dll_recalc(
struct
clk
*
clk
)
57
{
58
unsigned
long
mult
;
59
60
if
(
__raw_readl
(
PLLCR
) & 0x1000)
61
mult =
__raw_readl
(
DLLFRQ
);
62
else
63
mult = 0;
64
65
return
clk->
parent
->rate *
mult
;
66
}
67
68
static
struct
sh_clk_ops
dll_clk_ops = {
69
.recalc = dll_recalc,
70
};
71
72
static
struct
clk dll_clk = {
73
.ops = &dll_clk_ops,
74
.parent = &r_clk,
75
.
flags
=
CLK_ENABLE_ON_INIT
,
76
};
77
78
static
unsigned
long
pll_recalc(
struct
clk *clk)
79
{
80
unsigned
long
mult = 1;
81
unsigned
long
div
= 1;
82
83
if
(
__raw_readl
(
PLLCR
) & 0x4000)
84
mult = (((
__raw_readl
(
FRQCR
) >> 24) & 0x1f) + 1);
85
else
86
div = 2;
87
88
return
(clk->
parent
->rate * mult) /
div
;
89
}
90
91
static
struct
sh_clk_ops
pll_clk_ops = {
92
.recalc = pll_recalc,
93
};
94
95
static
struct
clk pll_clk = {
96
.ops = &pll_clk_ops,
97
.flags =
CLK_ENABLE_ON_INIT
,
98
};
99
100
struct
clk *
main_clks
[] = {
101
&r_clk,
102
&extal_clk,
103
&dll_clk,
104
&pll_clk,
105
};
106
107
static
int
multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
108
static
int
divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
109
110
static
struct
clk_div_mult_table
div4_div_mult_table = {
111
.divisors =
divisors
,
112
.nr_divisors =
ARRAY_SIZE
(divisors),
113
.multipliers =
multipliers
,
114
.nr_multipliers =
ARRAY_SIZE
(multipliers),
115
};
116
117
static
struct
clk_div4_table
div4_table = {
118
.div_mult_table = &div4_div_mult_table,
119
};
120
121
enum
{
DIV4_I
,
DIV4_U
,
DIV4_SH
,
DIV4_B
,
DIV4_B3
,
DIV4_P
,
DIV4_NR
};
122
123
#define DIV4(_reg, _bit, _mask, _flags) \
124
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
125
126
struct
clk
div4_clks
[
DIV4_NR
] = {
127
[
DIV4_I
] =
DIV4
(
FRQCR
, 20, 0x0dbf,
CLK_ENABLE_ON_INIT
),
128
[
DIV4_U
] =
DIV4
(
FRQCR
, 16, 0x0dbf,
CLK_ENABLE_ON_INIT
),
129
[
DIV4_SH
] =
DIV4
(
FRQCR
, 12, 0x0dbf,
CLK_ENABLE_ON_INIT
),
130
[
DIV4_B
] =
DIV4
(
FRQCR
, 8, 0x0dbf,
CLK_ENABLE_ON_INIT
),
131
[
DIV4_B3
] =
DIV4
(
FRQCR
, 4, 0x0db4,
CLK_ENABLE_ON_INIT
),
132
[
DIV4_P
] =
DIV4
(
FRQCR
, 0, 0x0dbf, 0),
133
};
134
135
enum
{
DIV4_IRDA
,
DIV4_ENABLE_NR
};
136
137
struct
clk
div4_enable_clks
[
DIV4_ENABLE_NR
] = {
138
[
DIV4_IRDA
] =
DIV4
(
IRDACLKCR
, 0, 0x0dbf, 0),
139
};
140
141
enum
{
DIV4_SIUA
,
DIV4_SIUB
,
DIV4_REPARENT_NR
};
142
143
struct
clk
div4_reparent_clks
[
DIV4_REPARENT_NR
] = {
144
[
DIV4_SIUA
] =
DIV4
(
SCLKACR
, 0, 0x0dbf, 0),
145
[
DIV4_SIUB
] =
DIV4
(
SCLKBCR
, 0, 0x0dbf, 0),
146
};
147
enum
{
DIV6_V
,
DIV6_NR
};
148
149
struct
clk
div6_clks
[
DIV6_NR
] = {
150
[
DIV6_V
] =
SH_CLK_DIV6
(&pll_clk,
VCLKCR
, 0),
151
};
152
153
static
struct
clk mstp_clks[] = {
154
/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
155
[
HWBLK_TLB
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 31,
CLK_ENABLE_ON_INIT
),
156
[
HWBLK_IC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 30,
CLK_ENABLE_ON_INIT
),
157
[
HWBLK_OC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 29,
CLK_ENABLE_ON_INIT
),
158
[
HWBLK_L2C
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_SH
],
MSTPCR0
, 28,
CLK_ENABLE_ON_INIT
),
159
[
HWBLK_ILMEM
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 27,
CLK_ENABLE_ON_INIT
),
160
[
HWBLK_FPU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 24,
CLK_ENABLE_ON_INIT
),
161
[
HWBLK_INTC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 22,
CLK_ENABLE_ON_INIT
),
162
[
HWBLK_DMAC0
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 21, 0),
163
[
HWBLK_SHYWAY
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_SH
],
MSTPCR0
, 20,
CLK_ENABLE_ON_INIT
),
164
[
HWBLK_HUDI
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 19, 0),
165
[
HWBLK_UBC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_I
],
MSTPCR0
, 17, 0),
166
[
HWBLK_TMU0
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 15, 0),
167
[
HWBLK_CMT
] =
SH_CLK_MSTP32
(&r_clk,
MSTPCR0
, 14, 0),
168
[
HWBLK_RWDT
] =
SH_CLK_MSTP32
(&r_clk,
MSTPCR0
, 13, 0),
169
[
HWBLK_DMAC1
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 12, 0),
170
[
HWBLK_TMU1
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 11, 0),
171
[
HWBLK_FLCTL
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 10, 0),
172
[
HWBLK_SCIF0
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 9, 0),
173
[
HWBLK_SCIF1
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 8, 0),
174
[
HWBLK_SCIF2
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR0
, 7, 0),
175
[
HWBLK_SCIF3
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 6, 0),
176
[
HWBLK_SCIF4
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 5, 0),
177
[
HWBLK_SCIF5
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 4, 0),
178
[
HWBLK_MSIOF0
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 2, 0),
179
[
HWBLK_MSIOF1
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR0
, 1, 0),
180
[
HWBLK_MERAM
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_SH
],
MSTPCR0
, 0, 0),
181
182
[
HWBLK_IIC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR1
, 9, 0),
183
[
HWBLK_RTC
] =
SH_CLK_MSTP32
(&r_clk,
MSTPCR1
, 8, 0),
184
185
[
HWBLK_ATAPI
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_SH
],
MSTPCR2
, 28, 0),
186
[
HWBLK_ADC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR2
, 27, 0),
187
[
HWBLK_TPU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 25, 0),
188
[
HWBLK_IRDA
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_P
],
MSTPCR2
, 24, 0),
189
[
HWBLK_TSIF
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 22, 0),
190
[
HWBLK_ICB
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 21,
CLK_ENABLE_ON_INIT
),
191
[
HWBLK_SDHI0
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 18, 0),
192
[
HWBLK_SDHI1
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 17, 0),
193
[
HWBLK_KEYSC
] =
SH_CLK_MSTP32
(&r_clk,
MSTPCR2
, 14, 0),
194
[
HWBLK_USB
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 11, 0),
195
[
HWBLK_2DG
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 10, 0),
196
[
HWBLK_SIU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 8, 0),
197
[
HWBLK_VEU2H1
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 6, 0),
198
[
HWBLK_VOU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 5, 0),
199
[
HWBLK_BEU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 4, 0),
200
[
HWBLK_CEU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 3, 0),
201
[
HWBLK_VEU2H0
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 2, 0),
202
[
HWBLK_VPU
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 1, 0),
203
[
HWBLK_LCDC
] =
SH_CLK_MSTP32
(&div4_clks[
DIV4_B
],
MSTPCR2
, 0, 0),
204
};
205
206
static
struct
clk_lookup
lookups[] = {
207
/* main clocks */
208
CLKDEV_CON_ID
(
"rclk"
, &r_clk),
209
CLKDEV_CON_ID
(
"extal"
, &extal_clk),
210
CLKDEV_CON_ID
(
"dll_clk"
, &dll_clk),
211
CLKDEV_CON_ID
(
"pll_clk"
, &pll_clk),
212
213
/* DIV4 clocks */
214
CLKDEV_CON_ID
(
"cpu_clk"
, &div4_clks[
DIV4_I
]),
215
CLKDEV_CON_ID
(
"umem_clk"
, &div4_clks[
DIV4_U
]),
216
CLKDEV_CON_ID
(
"shyway_clk"
, &div4_clks[
DIV4_SH
]),
217
CLKDEV_CON_ID
(
"bus_clk"
, &div4_clks[
DIV4_B
]),
218
CLKDEV_CON_ID
(
"b3_clk"
, &div4_clks[
DIV4_B3
]),
219
CLKDEV_CON_ID
(
"peripheral_clk"
, &div4_clks[
DIV4_P
]),
220
CLKDEV_CON_ID
(
"irda_clk"
, &div4_enable_clks[
DIV4_IRDA
]),
221
CLKDEV_CON_ID
(
"siua_clk"
, &div4_reparent_clks[
DIV4_SIUA
]),
222
CLKDEV_CON_ID
(
"siub_clk"
, &div4_reparent_clks[
DIV4_SIUB
]),
223
224
/* DIV6 clocks */
225
CLKDEV_CON_ID
(
"video_clk"
, &div6_clks[
DIV6_V
]),
226
227
/* MSTP clocks */
228
CLKDEV_CON_ID
(
"tlb0"
, &mstp_clks[
HWBLK_TLB
]),
229
CLKDEV_CON_ID
(
"ic0"
, &mstp_clks[
HWBLK_IC
]),
230
CLKDEV_CON_ID
(
"oc0"
, &mstp_clks[
HWBLK_OC
]),
231
CLKDEV_CON_ID
(
"l2c0"
, &mstp_clks[
HWBLK_L2C
]),
232
CLKDEV_CON_ID
(
"ilmem0"
, &mstp_clks[
HWBLK_ILMEM
]),
233
CLKDEV_CON_ID
(
"fpu0"
, &mstp_clks[
HWBLK_FPU
]),
234
CLKDEV_CON_ID
(
"intc0"
, &mstp_clks[
HWBLK_INTC
]),
235
CLKDEV_DEV_ID
(
"sh-dma-engine.0"
, &mstp_clks[
HWBLK_DMAC0
]),
236
CLKDEV_CON_ID
(
"sh0"
, &mstp_clks[
HWBLK_SHYWAY
]),
237
CLKDEV_CON_ID
(
"hudi0"
, &mstp_clks[
HWBLK_HUDI
]),
238
CLKDEV_CON_ID
(
"ubc0"
, &mstp_clks[
HWBLK_UBC
]),
239
CLKDEV_CON_ID
(
"cmt_fck"
, &mstp_clks[
HWBLK_CMT
]),
240
CLKDEV_DEV_ID
(
"sh-wdt.0"
, &mstp_clks[
HWBLK_RWDT
]),
241
CLKDEV_DEV_ID
(
"sh-dma-engine.1"
, &mstp_clks[
HWBLK_DMAC1
]),
242
CLKDEV_CON_ID
(
"flctl0"
, &mstp_clks[
HWBLK_FLCTL
]),
243
CLKDEV_DEV_ID
(
"spi_sh_msiof.0"
, &mstp_clks[
HWBLK_MSIOF0
]),
244
CLKDEV_DEV_ID
(
"spi_sh_msiof.1"
, &mstp_clks[
HWBLK_MSIOF1
]),
245
CLKDEV_DEV_ID
(
"sh_mobile_meram.0"
, &mstp_clks[
HWBLK_MERAM
]),
246
CLKDEV_DEV_ID
(
"i2c-sh_mobile.0"
, &mstp_clks[
HWBLK_IIC
]),
247
CLKDEV_CON_ID
(
"rtc0"
, &mstp_clks[
HWBLK_RTC
]),
248
CLKDEV_CON_ID
(
"atapi0"
, &mstp_clks[
HWBLK_ATAPI
]),
249
CLKDEV_CON_ID
(
"adc0"
, &mstp_clks[
HWBLK_ADC
]),
250
CLKDEV_CON_ID
(
"tpu0"
, &mstp_clks[
HWBLK_TPU
]),
251
CLKDEV_CON_ID
(
"irda0"
, &mstp_clks[
HWBLK_IRDA
]),
252
CLKDEV_CON_ID
(
"tsif0"
, &mstp_clks[
HWBLK_TSIF
]),
253
CLKDEV_CON_ID
(
"icb0"
, &mstp_clks[
HWBLK_ICB
]),
254
CLKDEV_DEV_ID
(
"sh_mobile_sdhi.0"
, &mstp_clks[
HWBLK_SDHI0
]),
255
CLKDEV_DEV_ID
(
"sh_mobile_sdhi.1"
, &mstp_clks[
HWBLK_SDHI1
]),
256
CLKDEV_DEV_ID
(
"sh_keysc.0"
, &mstp_clks[
HWBLK_KEYSC
]),
257
CLKDEV_CON_ID
(
"usb0"
, &mstp_clks[
HWBLK_USB
]),
258
CLKDEV_CON_ID
(
"2dg0"
, &mstp_clks[
HWBLK_2DG
]),
259
CLKDEV_DEV_ID
(
"siu-pcm-audio"
, &mstp_clks[
HWBLK_SIU
]),
260
CLKDEV_CON_ID
(
"veu1"
, &mstp_clks[
HWBLK_VEU2H1
]),
261
CLKDEV_DEV_ID
(
"sh-vou.0"
, &mstp_clks[
HWBLK_VOU
]),
262
CLKDEV_CON_ID
(
"beu0"
, &mstp_clks[
HWBLK_BEU
]),
263
CLKDEV_DEV_ID
(
"sh_mobile_ceu.0"
, &mstp_clks[
HWBLK_CEU
]),
264
CLKDEV_CON_ID
(
"veu0"
, &mstp_clks[
HWBLK_VEU2H0
]),
265
CLKDEV_CON_ID
(
"vpu0"
, &mstp_clks[
HWBLK_VPU
]),
266
267
CLKDEV_ICK_ID
(
"tmu_fck"
,
"sh_tmu.0"
, &mstp_clks[
HWBLK_TMU0
]),
268
CLKDEV_ICK_ID
(
"tmu_fck"
,
"sh_tmu.1"
, &mstp_clks[
HWBLK_TMU0
]),
269
CLKDEV_ICK_ID
(
"tmu_fck"
,
"sh_tmu.2"
, &mstp_clks[
HWBLK_TMU0
]),
270
CLKDEV_ICK_ID
(
"tmu_fck"
,
"sh_tmu.3"
, &mstp_clks[
HWBLK_TMU1
]),
271
CLKDEV_ICK_ID
(
"tmu_fck"
,
"sh_tmu.4"
, &mstp_clks[
HWBLK_TMU1
]),
272
CLKDEV_ICK_ID
(
"tmu_fck"
,
"sh_tmu.5"
, &mstp_clks[
HWBLK_TMU1
]),
273
274
CLKDEV_ICK_ID
(
"sci_fck"
,
"sh-sci.0"
, &mstp_clks[
HWBLK_SCIF0
]),
275
CLKDEV_ICK_ID
(
"sci_fck"
,
"sh-sci.1"
, &mstp_clks[
HWBLK_SCIF1
]),
276
CLKDEV_ICK_ID
(
"sci_fck"
,
"sh-sci.2"
, &mstp_clks[
HWBLK_SCIF2
]),
277
CLKDEV_ICK_ID
(
"sci_fck"
,
"sh-sci.3"
, &mstp_clks[
HWBLK_SCIF3
]),
278
CLKDEV_ICK_ID
(
"sci_fck"
,
"sh-sci.4"
, &mstp_clks[
HWBLK_SCIF4
]),
279
CLKDEV_ICK_ID
(
"sci_fck"
,
"sh-sci.5"
, &mstp_clks[
HWBLK_SCIF5
]),
280
281
CLKDEV_DEV_ID
(
"sh_mobile_lcdc_fb.0"
, &mstp_clks[
HWBLK_LCDC
]),
282
};
283
284
int
__init
arch_clk_init
(
void
)
285
{
286
int
k
,
ret
= 0;
287
288
/* autodetect extal or dll configuration */
289
if
(
__raw_readl
(
PLLCR
) & 0x1000)
290
pll_clk.
parent
= &dll_clk;
291
else
292
pll_clk.
parent
= &extal_clk;
293
294
for
(k = 0; !ret && (k <
ARRAY_SIZE
(main_clks)); k++)
295
ret |=
clk_register
(main_clks[k]);
296
297
clkdev_add_table
(lookups,
ARRAY_SIZE
(lookups));
298
299
if
(!ret)
300
ret =
sh_clk_div4_register
(div4_clks,
DIV4_NR
, &div4_table);
301
302
if
(!ret)
303
ret =
sh_clk_div4_enable_register
(div4_enable_clks,
304
DIV4_ENABLE_NR
, &div4_table);
305
306
if
(!ret)
307
ret =
sh_clk_div4_reparent_register
(div4_reparent_clks,
308
DIV4_REPARENT_NR
, &div4_table);
309
310
if
(!ret)
311
ret =
sh_clk_div6_register
(div6_clks,
DIV6_NR
);
312
313
if
(!ret)
314
ret =
sh_clk_mstp_register
(mstp_clks,
HWBLK_NR
);
315
316
return
ret
;
317
}
Generated on Thu Jan 10 2013 13:17:39 for Linux Kernel by
1.8.2