Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
c5eb5b37
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
c5eb5b37
编写于
5月 13, 2010
作者:
P
Paul Mundt
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'sh/clkfwk'
上级
15f2a796
f5ca6d4c
变更
23
隐藏空白更改
内联
并排
Showing
23 changed file
with
1698 addition
and
1326 deletion
+1698
-1326
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boards/mach-ecovec24/setup.c
+15
-11
arch/sh/boards/mach-highlander/setup.c
arch/sh/boards/mach-highlander/setup.c
+11
-1
arch/sh/boards/mach-se/7724/setup.c
arch/sh/boards/mach-se/7724/setup.c
+11
-9
arch/sh/include/asm/clock.h
arch/sh/include/asm/clock.h
+3
-150
arch/sh/kernel/cpu/Makefile
arch/sh/kernel/cpu/Makefile
+1
-1
arch/sh/kernel/cpu/clock-cpg.c
arch/sh/kernel/cpu/clock-cpg.c
+13
-294
arch/sh/kernel/cpu/clock.c
arch/sh/kernel/cpu/clock.c
+8
-568
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+13
-4
arch/sh/kernel/cpu/sh4a/clock-sh7343.c
arch/sh/kernel/cpu/sh4a/clock-sh7343.c
+146
-67
arch/sh/kernel/cpu/sh4a/clock-sh7366.c
arch/sh/kernel/cpu/sh4a/clock-sh7366.c
+130
-62
arch/sh/kernel/cpu/sh4a/clock-sh7722.c
arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+28
-19
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+28
-19
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+21
-17
arch/sh/kernel/cpu/sh4a/clock-sh7757.c
arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+10
-1
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+11
-1
arch/sh/kernel/cpu/sh4a/clock-sh7780.c
arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+11
-1
arch/sh/kernel/cpu/sh4a/clock-sh7785.c
arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+106
-43
arch/sh/kernel/cpu/sh4a/clock-sh7786.c
arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+125
-56
arch/sh/kernel/cpu/sh4a/clock-shx3.c
arch/sh/kernel/cpu/sh4a/clock-shx3.c
+11
-2
drivers/sh/Makefile
drivers/sh/Makefile
+2
-0
drivers/sh/clk-cpg.c
drivers/sh/clk-cpg.c
+298
-0
drivers/sh/clk.c
drivers/sh/clk.c
+545
-0
include/linux/sh_clk.h
include/linux/sh_clk.h
+151
-0
未找到文件。
arch/sh/boards/mach-ecovec24/setup.c
浏览文件 @
c5eb5b37
...
...
@@ -710,8 +710,6 @@ static struct clk_ops fsimck_clk_ops = {
};
static
struct
clk
fsimckb_clk
=
{
.
name
=
"fsimckb_clk"
,
.
id
=
-
1
,
.
ops
=
&
fsimck_clk_ops
,
.
enable_reg
=
(
void
__iomem
*
)
FCLKBCR
,
.
rate
=
0
,
/* unknown */
...
...
@@ -1138,16 +1136,20 @@ static int __init arch_setup(void)
/* set SPU2 clock to 83.4 MHz */
clk
=
clk_get
(
NULL
,
"spu_clk"
);
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
83333333
));
clk_put
(
clk
);
if
(
clk
)
{
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
83333333
));
clk_put
(
clk
);
}
/* change parent of FSI B */
clk
=
clk_get
(
NULL
,
"fsib_clk"
);
clk_register
(
&
fsimckb_clk
);
clk_set_parent
(
clk
,
&
fsimckb_clk
);
clk_set_rate
(
clk
,
11000
);
clk_set_rate
(
&
fsimckb_clk
,
11000
);
clk_put
(
clk
);
if
(
clk
)
{
clk_register
(
&
fsimckb_clk
);
clk_set_parent
(
clk
,
&
fsimckb_clk
);
clk_set_rate
(
clk
,
11000
);
clk_set_rate
(
&
fsimckb_clk
,
11000
);
clk_put
(
clk
);
}
gpio_request
(
GPIO_PTU0
,
NULL
);
gpio_direction_output
(
GPIO_PTU0
,
0
);
...
...
@@ -1159,8 +1161,10 @@ static int __init arch_setup(void)
/* set VPU clock to 166 MHz */
clk
=
clk_get
(
NULL
,
"vpu_clk"
);
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
166000000
));
clk_put
(
clk
);
if
(
clk
)
{
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
166000000
));
clk_put
(
clk
);
}
/* enable IrDA */
gpio_request
(
GPIO_FN_IRDA_OUT
,
NULL
);
...
...
arch/sh/boards/mach-highlander/setup.c
浏览文件 @
c5eb5b37
...
...
@@ -14,6 +14,7 @@
* for more details.
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/types.h>
...
...
@@ -26,6 +27,7 @@
#include <net/ax88796.h>
#include <asm/machvec.h>
#include <mach/highlander.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/heartbeat.h>
#include <asm/io.h>
...
...
@@ -326,7 +328,6 @@ static struct clk_ops ivdr_clk_ops = {
};
static
struct
clk
ivdr_clk
=
{
.
name
=
"ivdr_clk"
,
.
ops
=
&
ivdr_clk_ops
,
};
...
...
@@ -334,6 +335,13 @@ static struct clk *r7780rp_clocks[] = {
&
ivdr_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"ivdr_clk"
,
&
ivdr_clk
),
};
static
void
r7780rp_power_off
(
void
)
{
if
(
mach_is_r7780mp
()
||
mach_is_r7785rp
())
...
...
@@ -370,6 +378,8 @@ static void __init highlander_setup(char **cmdline_p)
clk_enable
(
clk
);
}
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
__raw_writew
(
0x0000
,
PA_OBLED
);
/* Clear LED. */
if
(
mach_is_r7780rp
())
...
...
arch/sh/boards/mach-se/7724/setup.c
浏览文件 @
c5eb5b37
...
...
@@ -276,8 +276,6 @@ static struct clk_ops fsimck_clk_ops = {
};
static
struct
clk
fsimcka_clk
=
{
.
name
=
"fsimcka_clk"
,
.
id
=
-
1
,
.
ops
=
&
fsimck_clk_ops
,
.
enable_reg
=
(
void
__iomem
*
)
FCLKACR
,
.
rate
=
0
,
/* unknown */
...
...
@@ -771,16 +769,20 @@ static int __init devices_setup(void)
/* set SPU2 clock to 83.4 MHz */
clk
=
clk_get
(
NULL
,
"spu_clk"
);
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
83333333
));
clk_put
(
clk
);
if
(
clk
)
{
clk_set_rate
(
clk
,
clk_round_rate
(
clk
,
83333333
));
clk_put
(
clk
);
}
/* change parent of FSI A */
clk
=
clk_get
(
NULL
,
"fsia_clk"
);
clk_register
(
&
fsimcka_clk
);
clk_set_parent
(
clk
,
&
fsimcka_clk
);
clk_set_rate
(
clk
,
11000
);
clk_set_rate
(
&
fsimcka_clk
,
11000
);
clk_put
(
clk
);
if
(
clk
)
{
clk_register
(
&
fsimcka_clk
);
clk_set_parent
(
clk
,
&
fsimcka_clk
);
clk_set_rate
(
clk
,
11000
);
clk_set_rate
(
&
fsimcka_clk
,
11000
);
clk_put
(
clk
);
}
/* SDHI0 connected to cn7 */
gpio_request
(
GPIO_FN_SDHI0CD
,
NULL
);
...
...
arch/sh/include/asm/clock.h
浏览文件 @
c5eb5b37
#ifndef __ASM_SH_CLOCK_H
#define __ASM_SH_CLOCK_H
#include <linux/list.h>
#include <linux/seq_file.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/err.h>
struct
clk
;
struct
clk_ops
{
void
(
*
init
)(
struct
clk
*
clk
);
int
(
*
enable
)(
struct
clk
*
clk
);
void
(
*
disable
)(
struct
clk
*
clk
);
unsigned
long
(
*
recalc
)(
struct
clk
*
clk
);
int
(
*
set_rate
)(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
);
int
(
*
set_parent
)(
struct
clk
*
clk
,
struct
clk
*
parent
);
long
(
*
round_rate
)(
struct
clk
*
clk
,
unsigned
long
rate
);
};
struct
clk
{
struct
list_head
node
;
const
char
*
name
;
int
id
;
struct
module
*
owner
;
struct
clk
*
parent
;
struct
clk_ops
*
ops
;
struct
list_head
children
;
struct
list_head
sibling
;
/* node for children */
int
usecount
;
unsigned
long
rate
;
unsigned
long
flags
;
void
__iomem
*
enable_reg
;
unsigned
int
enable_bit
;
unsigned
long
arch_flags
;
void
*
priv
;
struct
dentry
*
dentry
;
struct
cpufreq_frequency_table
*
freq_table
;
};
#define CLK_ENABLE_ON_INIT (1 << 0)
#include <linux/sh_clk.h>
/* Should be defined by processor-specific code */
void
__deprecated
arch_init_clk_ops
(
struct
clk_ops
**
,
int
type
);
int
__init
arch_clk_init
(
void
);
/* arch/sh/kernel/cpu/clock.c */
int
clk_init
(
void
);
unsigned
long
followparent_recalc
(
struct
clk
*
);
void
recalculate_root_clocks
(
void
);
void
propagate_rate
(
struct
clk
*
);
int
clk_reparent
(
struct
clk
*
child
,
struct
clk
*
parent
);
int
clk_register
(
struct
clk
*
);
void
clk_unregister
(
struct
clk
*
);
/* arch/sh/kernel/cpu/clock-cpg.c */
int
__init
__deprecated
cpg_clk_init
(
void
);
/* the exported API, in addition to clk_set_rate */
/**
* clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
* @clk: clock source
* @rate: desired clock rate in Hz
* @algo_id: algorithm id to be passed down to ops->set_rate
*
* Returns success (0) or negative errno.
*/
int
clk_set_rate_ex
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
);
enum
clk_sh_algo_id
{
NO_CHANGE
=
0
,
IUS_N1_N1
,
IUS_322
,
IUS_522
,
IUS_N11
,
SB_N1
,
SB3_N1
,
SB3_32
,
SB3_43
,
SB3_54
,
BP_N1
,
IP_N1
,
};
struct
clk_div_mult_table
{
unsigned
int
*
divisors
;
unsigned
int
nr_divisors
;
unsigned
int
*
multipliers
;
unsigned
int
nr_multipliers
;
};
struct
cpufreq_frequency_table
;
void
clk_rate_table_build
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
int
nr_freqs
,
struct
clk_div_mult_table
*
src_table
,
unsigned
long
*
bitmap
);
long
clk_rate_table_round
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
);
int
clk_rate_table_find
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
);
#define SH_CLK_MSTP32(_name, _id, _parent, _enable_reg, \
_enable_bit, _flags) \
{ \
.name = _name, \
.id = _id, \
.parent = _parent, \
.enable_reg = (void __iomem *)_enable_reg, \
.enable_bit = _enable_bit, \
.flags = _flags, \
}
int
sh_clk_mstp32_register
(
struct
clk
*
clks
,
int
nr
);
#define SH_CLK_DIV4(_name, _parent, _reg, _shift, _div_bitmap, _flags) \
{ \
.name = _name, \
.parent = _parent, \
.enable_reg = (void __iomem *)_reg, \
.enable_bit = _shift, \
.arch_flags = _div_bitmap, \
.flags = _flags, \
}
struct
clk_div4_table
{
struct
clk_div_mult_table
*
div_mult_table
;
void
(
*
kick
)(
struct
clk
*
clk
);
};
int
sh_clk_div4_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
);
int
sh_clk_div4_enable_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
);
int
sh_clk_div4_reparent_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
);
#define SH_CLK_DIV6(_parent, _reg, _flags) \
{ \
.parent = _parent, \
.enable_reg = (void __iomem *)_reg, \
.flags = _flags, \
}
int
sh_clk_div6_register
(
struct
clk
*
clks
,
int
nr
);
/* arch/sh/kernel/cpu/clock.c */
int
clk_init
(
void
);
#endif
/* __ASM_SH_CLOCK_H */
arch/sh/kernel/cpu/Makefile
浏览文件 @
c5eb5b37
...
...
@@ -16,7 +16,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
# Common interfaces.
obj-$(CONFIG_SH_ADC)
+=
adc.o
obj-$(CONFIG_SH_CLK_CPG)
+=
clock-cpg.o
obj-$(CONFIG_SH_CLK_CPG
_LEGACY
)
+=
clock-cpg.o
obj-$(CONFIG_SH_FPU)
+=
fpu.o
obj-$(CONFIG_SH_FPU_EMU)
+=
fpu.o
...
...
arch/sh/kernel/cpu/clock-cpg.c
浏览文件 @
c5eb5b37
...
...
@@ -2,317 +2,25 @@
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
static
int
sh_clk_mstp32_enable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
&
~
(
1
<<
clk
->
enable_bit
),
clk
->
enable_reg
);
return
0
;
}
static
void
sh_clk_mstp32_disable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
|
(
1
<<
clk
->
enable_bit
),
clk
->
enable_reg
);
}
static
struct
clk_ops
sh_clk_mstp32_clk_ops
=
{
.
enable
=
sh_clk_mstp32_enable
,
.
disable
=
sh_clk_mstp32_disable
,
.
recalc
=
followparent_recalc
,
};
int
__init
sh_clk_mstp32_register
(
struct
clk
*
clks
,
int
nr
)
{
struct
clk
*
clkp
;
int
ret
=
0
;
int
k
;
for
(
k
=
0
;
!
ret
&&
(
k
<
nr
);
k
++
)
{
clkp
=
clks
+
k
;
clkp
->
ops
=
&
sh_clk_mstp32_clk_ops
;
ret
|=
clk_register
(
clkp
);
}
return
ret
;
}
static
long
sh_clk_div_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
clk_rate_table_round
(
clk
,
clk
->
freq_table
,
rate
);
}
static
int
sh_clk_div6_divisors
[
64
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
};
static
struct
clk_div_mult_table
sh_clk_div6_table
=
{
.
divisors
=
sh_clk_div6_divisors
,
.
nr_divisors
=
ARRAY_SIZE
(
sh_clk_div6_divisors
),
};
static
unsigned
long
sh_clk_div6_recalc
(
struct
clk
*
clk
)
{
struct
clk_div_mult_table
*
table
=
&
sh_clk_div6_table
;
unsigned
int
idx
;
clk_rate_table_build
(
clk
,
clk
->
freq_table
,
table
->
nr_divisors
,
table
,
NULL
);
idx
=
__raw_readl
(
clk
->
enable_reg
)
&
0x003f
;
return
clk
->
freq_table
[
idx
].
frequency
;
}
static
int
sh_clk_div6_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
)
{
unsigned
long
value
;
int
idx
;
idx
=
clk_rate_table_find
(
clk
,
clk
->
freq_table
,
rate
);
if
(
idx
<
0
)
return
idx
;
value
=
__raw_readl
(
clk
->
enable_reg
);
value
&=
~
0x3f
;
value
|=
idx
;
__raw_writel
(
value
,
clk
->
enable_reg
);
return
0
;
}
static
int
sh_clk_div6_enable
(
struct
clk
*
clk
)
{
unsigned
long
value
;
int
ret
;
ret
=
sh_clk_div6_set_rate
(
clk
,
clk
->
rate
,
0
);
if
(
ret
==
0
)
{
value
=
__raw_readl
(
clk
->
enable_reg
);
value
&=
~
0x100
;
/* clear stop bit to enable clock */
__raw_writel
(
value
,
clk
->
enable_reg
);
}
return
ret
;
}
static
void
sh_clk_div6_disable
(
struct
clk
*
clk
)
{
unsigned
long
value
;
value
=
__raw_readl
(
clk
->
enable_reg
);
value
|=
0x100
;
/* stop clock */
value
|=
0x3f
;
/* VDIV bits must be non-zero, overwrite divider */
__raw_writel
(
value
,
clk
->
enable_reg
);
}
static
struct
clk_ops
sh_clk_div6_clk_ops
=
{
.
recalc
=
sh_clk_div6_recalc
,
.
round_rate
=
sh_clk_div_round_rate
,
.
set_rate
=
sh_clk_div6_set_rate
,
.
enable
=
sh_clk_div6_enable
,
.
disable
=
sh_clk_div6_disable
,
};
int
__init
sh_clk_div6_register
(
struct
clk
*
clks
,
int
nr
)
{
struct
clk
*
clkp
;
void
*
freq_table
;
int
nr_divs
=
sh_clk_div6_table
.
nr_divisors
;
int
freq_table_size
=
sizeof
(
struct
cpufreq_frequency_table
);
int
ret
=
0
;
int
k
;
freq_table_size
*=
(
nr_divs
+
1
);
freq_table
=
kzalloc
(
freq_table_size
*
nr
,
GFP_KERNEL
);
if
(
!
freq_table
)
{
pr_err
(
"sh_clk_div6_register: unable to alloc memory
\n
"
);
return
-
ENOMEM
;
}
for
(
k
=
0
;
!
ret
&&
(
k
<
nr
);
k
++
)
{
clkp
=
clks
+
k
;
clkp
->
ops
=
&
sh_clk_div6_clk_ops
;
clkp
->
id
=
-
1
;
clkp
->
freq_table
=
freq_table
+
(
k
*
freq_table_size
);
clkp
->
freq_table
[
nr_divs
].
frequency
=
CPUFREQ_TABLE_END
;
ret
=
clk_register
(
clkp
);
}
return
ret
;
}
static
unsigned
long
sh_clk_div4_recalc
(
struct
clk
*
clk
)
{
struct
clk_div4_table
*
d4t
=
clk
->
priv
;
struct
clk_div_mult_table
*
table
=
d4t
->
div_mult_table
;
unsigned
int
idx
;
clk_rate_table_build
(
clk
,
clk
->
freq_table
,
table
->
nr_divisors
,
table
,
&
clk
->
arch_flags
);
idx
=
(
__raw_readl
(
clk
->
enable_reg
)
>>
clk
->
enable_bit
)
&
0x000f
;
return
clk
->
freq_table
[
idx
].
frequency
;
}
static
int
sh_clk_div4_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
struct
clk_div4_table
*
d4t
=
clk
->
priv
;
struct
clk_div_mult_table
*
table
=
d4t
->
div_mult_table
;
u32
value
;
int
ret
;
if
(
!
strcmp
(
"pll_clk"
,
parent
->
name
))
value
=
__raw_readl
(
clk
->
enable_reg
)
&
~
(
1
<<
7
);
else
value
=
__raw_readl
(
clk
->
enable_reg
)
|
(
1
<<
7
);
ret
=
clk_reparent
(
clk
,
parent
);
if
(
ret
<
0
)
return
ret
;
__raw_writel
(
value
,
clk
->
enable_reg
);
/* Rebiuld the frequency table */
clk_rate_table_build
(
clk
,
clk
->
freq_table
,
table
->
nr_divisors
,
table
,
&
clk
->
arch_flags
);
return
0
;
}
static
int
sh_clk_div4_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
)
{
struct
clk_div4_table
*
d4t
=
clk
->
priv
;
unsigned
long
value
;
int
idx
=
clk_rate_table_find
(
clk
,
clk
->
freq_table
,
rate
);
if
(
idx
<
0
)
return
idx
;
value
=
__raw_readl
(
clk
->
enable_reg
);
value
&=
~
(
0xf
<<
clk
->
enable_bit
);
value
|=
(
idx
<<
clk
->
enable_bit
);
__raw_writel
(
value
,
clk
->
enable_reg
);
if
(
d4t
->
kick
)
d4t
->
kick
(
clk
);
return
0
;
}
static
int
sh_clk_div4_enable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
&
~
(
1
<<
8
),
clk
->
enable_reg
);
return
0
;
}
static
void
sh_clk_div4_disable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
|
(
1
<<
8
),
clk
->
enable_reg
);
}
static
struct
clk_ops
sh_clk_div4_clk_ops
=
{
.
recalc
=
sh_clk_div4_recalc
,
.
set_rate
=
sh_clk_div4_set_rate
,
.
round_rate
=
sh_clk_div_round_rate
,
};
static
struct
clk_ops
sh_clk_div4_enable_clk_ops
=
{
.
recalc
=
sh_clk_div4_recalc
,
.
set_rate
=
sh_clk_div4_set_rate
,
.
round_rate
=
sh_clk_div_round_rate
,
.
enable
=
sh_clk_div4_enable
,
.
disable
=
sh_clk_div4_disable
,
};
static
struct
clk_ops
sh_clk_div4_reparent_clk_ops
=
{
.
recalc
=
sh_clk_div4_recalc
,
.
set_rate
=
sh_clk_div4_set_rate
,
.
round_rate
=
sh_clk_div_round_rate
,
.
enable
=
sh_clk_div4_enable
,
.
disable
=
sh_clk_div4_disable
,
.
set_parent
=
sh_clk_div4_set_parent
,
};
static
int
__init
sh_clk_div4_register_ops
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
,
struct
clk_ops
*
ops
)
{
struct
clk
*
clkp
;
void
*
freq_table
;
int
nr_divs
=
table
->
div_mult_table
->
nr_divisors
;
int
freq_table_size
=
sizeof
(
struct
cpufreq_frequency_table
);
int
ret
=
0
;
int
k
;
freq_table_size
*=
(
nr_divs
+
1
);
freq_table
=
kzalloc
(
freq_table_size
*
nr
,
GFP_KERNEL
);
if
(
!
freq_table
)
{
pr_err
(
"sh_clk_div4_register: unable to alloc memory
\n
"
);
return
-
ENOMEM
;
}
for
(
k
=
0
;
!
ret
&&
(
k
<
nr
);
k
++
)
{
clkp
=
clks
+
k
;
clkp
->
ops
=
ops
;
clkp
->
id
=
-
1
;
clkp
->
priv
=
table
;
clkp
->
freq_table
=
freq_table
+
(
k
*
freq_table_size
);
clkp
->
freq_table
[
nr_divs
].
frequency
=
CPUFREQ_TABLE_END
;
ret
=
clk_register
(
clkp
);
}
return
ret
;
}
int
__init
sh_clk_div4_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
)
{
return
sh_clk_div4_register_ops
(
clks
,
nr
,
table
,
&
sh_clk_div4_clk_ops
);
}
int
__init
sh_clk_div4_enable_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
)
{
return
sh_clk_div4_register_ops
(
clks
,
nr
,
table
,
&
sh_clk_div4_enable_clk_ops
);
}
int
__init
sh_clk_div4_reparent_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
)
{
return
sh_clk_div4_register_ops
(
clks
,
nr
,
table
,
&
sh_clk_div4_reparent_clk_ops
);
}
#ifdef CONFIG_SH_CLK_CPG_LEGACY
static
struct
clk
master_clk
=
{
.
name
=
"master_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
rate
=
CONFIG_SH_PCLK_FREQ
,
};
static
struct
clk
peripheral_clk
=
{
.
name
=
"peripheral_clk"
,
.
parent
=
&
master_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
static
struct
clk
bus_clk
=
{
.
name
=
"bus_clk"
,
.
parent
=
&
master_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
static
struct
clk
cpu_clk
=
{
.
name
=
"cpu_clk"
,
.
parent
=
&
master_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
...
...
@@ -327,6 +35,16 @@ static struct clk *onchip_clocks[] = {
&
cpu_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"master_clk"
,
&
master_clk
),
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
peripheral_clk
),
CLKDEV_CON_ID
(
"bus_clk"
,
&
bus_clk
),
CLKDEV_CON_ID
(
"cpu_clk"
,
&
cpu_clk
),
};
int
__init
__deprecated
cpg_clk_init
(
void
)
{
int
i
,
ret
=
0
;
...
...
@@ -338,6 +56,8 @@ int __init __deprecated cpg_clk_init(void)
ret
|=
clk_register
(
clk
);
}
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
clk_add_alias
(
"tmu_fck"
,
NULL
,
"peripheral_clk"
,
NULL
);
clk_add_alias
(
"mtu2_fck"
,
NULL
,
"peripheral_clk"
,
NULL
);
clk_add_alias
(
"cmt_fck"
,
NULL
,
"peripheral_clk"
,
NULL
);
...
...
@@ -354,4 +74,3 @@ int __init __weak arch_clk_init(void)
{
return
cpg_clk_init
();
}
#endif
/* CONFIG_SH_CPG_CLK_LEGACY */
arch/sh/kernel/cpu/clock.c
浏览文件 @
c5eb5b37
...
...
@@ -16,500 +16,10 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/kobject.h>
#include <linux/sysdev.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <asm/clock.h>
#include <asm/machvec.h>
static
LIST_HEAD
(
clock_list
);
static
DEFINE_SPINLOCK
(
clock_lock
);
static
DEFINE_MUTEX
(
clock_list_sem
);
void
clk_rate_table_build
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
int
nr_freqs
,
struct
clk_div_mult_table
*
src_table
,
unsigned
long
*
bitmap
)
{
unsigned
long
mult
,
div
;
unsigned
long
freq
;
int
i
;
for
(
i
=
0
;
i
<
nr_freqs
;
i
++
)
{
div
=
1
;
mult
=
1
;
if
(
src_table
->
divisors
&&
i
<
src_table
->
nr_divisors
)
div
=
src_table
->
divisors
[
i
];
if
(
src_table
->
multipliers
&&
i
<
src_table
->
nr_multipliers
)
mult
=
src_table
->
multipliers
[
i
];
if
(
!
div
||
!
mult
||
(
bitmap
&&
!
test_bit
(
i
,
bitmap
)))
freq
=
CPUFREQ_ENTRY_INVALID
;
else
freq
=
clk
->
parent
->
rate
*
mult
/
div
;
freq_table
[
i
].
index
=
i
;
freq_table
[
i
].
frequency
=
freq
;
}
/* Termination entry */
freq_table
[
i
].
index
=
i
;
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
}
long
clk_rate_table_round
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
)
{
unsigned
long
rate_error
,
rate_error_prev
=
~
0UL
;
unsigned
long
rate_best_fit
=
rate
;
unsigned
long
highest
,
lowest
;
int
i
;
highest
=
lowest
=
0
;
for
(
i
=
0
;
freq_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
unsigned
long
freq
=
freq_table
[
i
].
frequency
;
if
(
freq
==
CPUFREQ_ENTRY_INVALID
)
continue
;
if
(
freq
>
highest
)
highest
=
freq
;
if
(
freq
<
lowest
)
lowest
=
freq
;
rate_error
=
abs
(
freq
-
rate
);
if
(
rate_error
<
rate_error_prev
)
{
rate_best_fit
=
freq
;
rate_error_prev
=
rate_error
;
}
if
(
rate_error
==
0
)
break
;
}
if
(
rate
>=
highest
)
rate_best_fit
=
highest
;
if
(
rate
<=
lowest
)
rate_best_fit
=
lowest
;
return
rate_best_fit
;
}
int
clk_rate_table_find
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
)
{
int
i
;
for
(
i
=
0
;
freq_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
unsigned
long
freq
=
freq_table
[
i
].
frequency
;
if
(
freq
==
CPUFREQ_ENTRY_INVALID
)
continue
;
if
(
freq
==
rate
)
return
i
;
}
return
-
ENOENT
;
}
/* Used for clocks that always have same value as the parent clock */
unsigned
long
followparent_recalc
(
struct
clk
*
clk
)
{
return
clk
->
parent
?
clk
->
parent
->
rate
:
0
;
}
int
clk_reparent
(
struct
clk
*
child
,
struct
clk
*
parent
)
{
list_del_init
(
&
child
->
sibling
);
if
(
parent
)
list_add
(
&
child
->
sibling
,
&
parent
->
children
);
child
->
parent
=
parent
;
/* now do the debugfs renaming to reattach the child
to the proper parent */
return
0
;
}
/* Propagate rate to children */
void
propagate_rate
(
struct
clk
*
tclk
)
{
struct
clk
*
clkp
;
list_for_each_entry
(
clkp
,
&
tclk
->
children
,
sibling
)
{
if
(
clkp
->
ops
&&
clkp
->
ops
->
recalc
)
clkp
->
rate
=
clkp
->
ops
->
recalc
(
clkp
);
propagate_rate
(
clkp
);
}
}
static
void
__clk_disable
(
struct
clk
*
clk
)
{
if
(
clk
->
usecount
==
0
)
{
printk
(
KERN_ERR
"Trying disable clock %s with 0 usecount
\n
"
,
clk
->
name
);
WARN_ON
(
1
);
return
;
}
if
(
!
(
--
clk
->
usecount
))
{
if
(
likely
(
clk
->
ops
&&
clk
->
ops
->
disable
))
clk
->
ops
->
disable
(
clk
);
if
(
likely
(
clk
->
parent
))
__clk_disable
(
clk
->
parent
);
}
}
void
clk_disable
(
struct
clk
*
clk
)
{
unsigned
long
flags
;
if
(
!
clk
)
return
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
__clk_disable
(
clk
);
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
clk_disable
);
static
int
__clk_enable
(
struct
clk
*
clk
)
{
int
ret
=
0
;
if
(
clk
->
usecount
++
==
0
)
{
if
(
clk
->
parent
)
{
ret
=
__clk_enable
(
clk
->
parent
);
if
(
unlikely
(
ret
))
goto
err
;
}
if
(
clk
->
ops
&&
clk
->
ops
->
enable
)
{
ret
=
clk
->
ops
->
enable
(
clk
);
if
(
ret
)
{
if
(
clk
->
parent
)
__clk_disable
(
clk
->
parent
);
goto
err
;
}
}
}
return
ret
;
err:
clk
->
usecount
--
;
return
ret
;
}
int
clk_enable
(
struct
clk
*
clk
)
{
unsigned
long
flags
;
int
ret
;
if
(
!
clk
)
return
-
EINVAL
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
ret
=
__clk_enable
(
clk
);
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
clk_enable
);
static
LIST_HEAD
(
root_clks
);
/**
* recalculate_root_clocks - recalculate and propagate all root clocks
*
* Recalculates all root clocks (clocks with no parent), which if the
* clock's .recalc is set correctly, should also propagate their rates.
* Called at init.
*/
void
recalculate_root_clocks
(
void
)
{
struct
clk
*
clkp
;
list_for_each_entry
(
clkp
,
&
root_clks
,
sibling
)
{
if
(
clkp
->
ops
&&
clkp
->
ops
->
recalc
)
clkp
->
rate
=
clkp
->
ops
->
recalc
(
clkp
);
propagate_rate
(
clkp
);
}
}
int
clk_register
(
struct
clk
*
clk
)
{
if
(
clk
==
NULL
||
IS_ERR
(
clk
))
return
-
EINVAL
;
/*
* trap out already registered clocks
*/
if
(
clk
->
node
.
next
||
clk
->
node
.
prev
)
return
0
;
mutex_lock
(
&
clock_list_sem
);
INIT_LIST_HEAD
(
&
clk
->
children
);
clk
->
usecount
=
0
;
if
(
clk
->
parent
)
list_add
(
&
clk
->
sibling
,
&
clk
->
parent
->
children
);
else
list_add
(
&
clk
->
sibling
,
&
root_clks
);
list_add
(
&
clk
->
node
,
&
clock_list
);
if
(
clk
->
ops
&&
clk
->
ops
->
init
)
clk
->
ops
->
init
(
clk
);
mutex_unlock
(
&
clock_list_sem
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
clk_register
);
void
clk_unregister
(
struct
clk
*
clk
)
{
mutex_lock
(
&
clock_list_sem
);
list_del
(
&
clk
->
sibling
);
list_del
(
&
clk
->
node
);
mutex_unlock
(
&
clock_list_sem
);
}
EXPORT_SYMBOL_GPL
(
clk_unregister
);
static
void
clk_enable_init_clocks
(
void
)
{
struct
clk
*
clkp
;
list_for_each_entry
(
clkp
,
&
clock_list
,
node
)
if
(
clkp
->
flags
&
CLK_ENABLE_ON_INIT
)
clk_enable
(
clkp
);
}
unsigned
long
clk_get_rate
(
struct
clk
*
clk
)
{
return
clk
->
rate
;
}
EXPORT_SYMBOL_GPL
(
clk_get_rate
);
int
clk_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
clk_set_rate_ex
(
clk
,
rate
,
0
);
}
EXPORT_SYMBOL_GPL
(
clk_set_rate
);
int
clk_set_rate_ex
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
)
{
int
ret
=
-
EOPNOTSUPP
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
if
(
likely
(
clk
->
ops
&&
clk
->
ops
->
set_rate
))
{
ret
=
clk
->
ops
->
set_rate
(
clk
,
rate
,
algo_id
);
if
(
ret
!=
0
)
goto
out_unlock
;
}
else
{
clk
->
rate
=
rate
;
ret
=
0
;
}
if
(
clk
->
ops
&&
clk
->
ops
->
recalc
)
clk
->
rate
=
clk
->
ops
->
recalc
(
clk
);
propagate_rate
(
clk
);
out_unlock:
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
clk_set_rate_ex
);
int
clk_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
flags
;
int
ret
=
-
EINVAL
;
if
(
!
parent
||
!
clk
)
return
ret
;
if
(
clk
->
parent
==
parent
)
return
0
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
if
(
clk
->
usecount
==
0
)
{
if
(
clk
->
ops
->
set_parent
)
ret
=
clk
->
ops
->
set_parent
(
clk
,
parent
);
else
ret
=
clk_reparent
(
clk
,
parent
);
if
(
ret
==
0
)
{
pr_debug
(
"clock: set parent of %s to %s (new rate %ld)
\n
"
,
clk
->
name
,
clk
->
parent
->
name
,
clk
->
rate
);
if
(
clk
->
ops
->
recalc
)
clk
->
rate
=
clk
->
ops
->
recalc
(
clk
);
propagate_rate
(
clk
);
}
}
else
ret
=
-
EBUSY
;
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
clk_set_parent
);
struct
clk
*
clk_get_parent
(
struct
clk
*
clk
)
{
return
clk
->
parent
;
}
EXPORT_SYMBOL_GPL
(
clk_get_parent
);
long
clk_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
if
(
likely
(
clk
->
ops
&&
clk
->
ops
->
round_rate
))
{
unsigned
long
flags
,
rounded
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
rounded
=
clk
->
ops
->
round_rate
(
clk
,
rate
);
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
rounded
;
}
return
clk_get_rate
(
clk
);
}
EXPORT_SYMBOL_GPL
(
clk_round_rate
);
/*
* Returns a clock. Note that we first try to use device id on the bus
* and clock name. If this fails, we try to use clock name only.
*/
struct
clk
*
clk_get
(
struct
device
*
dev
,
const
char
*
id
)
{
const
char
*
dev_id
=
dev
?
dev_name
(
dev
)
:
NULL
;
struct
clk
*
p
,
*
clk
=
ERR_PTR
(
-
ENOENT
);
int
idno
;
clk
=
clk_get_sys
(
dev_id
,
id
);
if
(
clk
&&
!
IS_ERR
(
clk
))
return
clk
;
if
(
dev
==
NULL
||
dev
->
bus
!=
&
platform_bus_type
)
idno
=
-
1
;
else
idno
=
to_platform_device
(
dev
)
->
id
;
mutex_lock
(
&
clock_list_sem
);
list_for_each_entry
(
p
,
&
clock_list
,
node
)
{
if
(
p
->
name
&&
p
->
id
==
idno
&&
strcmp
(
id
,
p
->
name
)
==
0
&&
try_module_get
(
p
->
owner
))
{
clk
=
p
;
goto
found
;
}
}
list_for_each_entry
(
p
,
&
clock_list
,
node
)
{
if
(
p
->
name
&&
strcmp
(
id
,
p
->
name
)
==
0
&&
try_module_get
(
p
->
owner
))
{
clk
=
p
;
break
;
}
}
found:
mutex_unlock
(
&
clock_list_sem
);
return
clk
;
}
EXPORT_SYMBOL_GPL
(
clk_get
);
void
clk_put
(
struct
clk
*
clk
)
{
if
(
clk
&&
!
IS_ERR
(
clk
))
module_put
(
clk
->
owner
);
}
EXPORT_SYMBOL_GPL
(
clk_put
);
#ifdef CONFIG_PM
static
int
clks_sysdev_suspend
(
struct
sys_device
*
dev
,
pm_message_t
state
)
{
static
pm_message_t
prev_state
;
struct
clk
*
clkp
;
switch
(
state
.
event
)
{
case
PM_EVENT_ON
:
/* Resumeing from hibernation */
if
(
prev_state
.
event
!=
PM_EVENT_FREEZE
)
break
;
list_for_each_entry
(
clkp
,
&
clock_list
,
node
)
{
if
(
likely
(
clkp
->
ops
))
{
unsigned
long
rate
=
clkp
->
rate
;
if
(
likely
(
clkp
->
ops
->
set_parent
))
clkp
->
ops
->
set_parent
(
clkp
,
clkp
->
parent
);
if
(
likely
(
clkp
->
ops
->
set_rate
))
clkp
->
ops
->
set_rate
(
clkp
,
rate
,
NO_CHANGE
);
else
if
(
likely
(
clkp
->
ops
->
recalc
))
clkp
->
rate
=
clkp
->
ops
->
recalc
(
clkp
);
}
}
break
;
case
PM_EVENT_FREEZE
:
break
;
case
PM_EVENT_SUSPEND
:
break
;
}
prev_state
=
state
;
return
0
;
}
static
int
clks_sysdev_resume
(
struct
sys_device
*
dev
)
{
return
clks_sysdev_suspend
(
dev
,
PMSG_ON
);
}
static
struct
sysdev_class
clks_sysdev_class
=
{
.
name
=
"clks"
,
};
static
struct
sysdev_driver
clks_sysdev_driver
=
{
.
suspend
=
clks_sysdev_suspend
,
.
resume
=
clks_sysdev_resume
,
};
static
struct
sys_device
clks_sysdev_dev
=
{
.
cls
=
&
clks_sysdev_class
,
};
static
int
__init
clk_sysdev_init
(
void
)
{
sysdev_class_register
(
&
clks_sysdev_class
);
sysdev_driver_register
(
&
clks_sysdev_class
,
&
clks_sysdev_driver
);
sysdev_register
(
&
clks_sysdev_dev
);
return
0
;
}
subsys_initcall
(
clk_sysdev_init
);
#endif
int
__init
clk_init
(
void
)
{
int
ret
;
...
...
@@ -539,89 +49,19 @@ int __init clk_init(void)
}
/*
* debugfs support to trace clock tree hierarchy and attributes
* Returns a clock. Note that we first try to use device id on the bus
* and clock name. If this fails, we try to use clock name only.
*/
static
struct
dentry
*
clk_debugfs_root
;
static
int
clk_debugfs_register_one
(
struct
clk
*
c
)
struct
clk
*
clk_get
(
struct
device
*
dev
,
const
char
*
con_id
)
{
int
err
;
struct
dentry
*
d
,
*
child
,
*
child_tmp
;
struct
clk
*
pa
=
c
->
parent
;
char
s
[
255
];
char
*
p
=
s
;
p
+=
sprintf
(
p
,
"%s"
,
c
->
name
);
if
(
c
->
id
>=
0
)
sprintf
(
p
,
":%d"
,
c
->
id
);
d
=
debugfs_create_dir
(
s
,
pa
?
pa
->
dentry
:
clk_debugfs_root
);
if
(
!
d
)
return
-
ENOMEM
;
c
->
dentry
=
d
;
d
=
debugfs_create_u8
(
"usecount"
,
S_IRUGO
,
c
->
dentry
,
(
u8
*
)
&
c
->
usecount
);
if
(
!
d
)
{
err
=
-
ENOMEM
;
goto
err_out
;
}
d
=
debugfs_create_u32
(
"rate"
,
S_IRUGO
,
c
->
dentry
,
(
u32
*
)
&
c
->
rate
);
if
(
!
d
)
{
err
=
-
ENOMEM
;
goto
err_out
;
}
d
=
debugfs_create_x32
(
"flags"
,
S_IRUGO
,
c
->
dentry
,
(
u32
*
)
&
c
->
flags
);
if
(
!
d
)
{
err
=
-
ENOMEM
;
goto
err_out
;
}
return
0
;
const
char
*
dev_id
=
dev
?
dev_name
(
dev
)
:
NULL
;
err_out:
d
=
c
->
dentry
;
list_for_each_entry_safe
(
child
,
child_tmp
,
&
d
->
d_subdirs
,
d_u
.
d_child
)
debugfs_remove
(
child
);
debugfs_remove
(
c
->
dentry
);
return
err
;
return
clk_get_sys
(
dev_id
,
con_id
);
}
EXPORT_SYMBOL_GPL
(
clk_get
);
static
int
clk_debugfs_register
(
struct
clk
*
c
)
void
clk_put
(
struct
clk
*
clk
)
{
int
err
;
struct
clk
*
pa
=
c
->
parent
;
if
(
pa
&&
!
pa
->
dentry
)
{
err
=
clk_debugfs_register
(
pa
);
if
(
err
)
return
err
;
}
if
(
!
c
->
dentry
&&
c
->
name
)
{
err
=
clk_debugfs_register_one
(
c
);
if
(
err
)
return
err
;
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
clk_put
);
static
int
__init
clk_debugfs_init
(
void
)
{
struct
clk
*
c
;
struct
dentry
*
d
;
int
err
;
d
=
debugfs_create_dir
(
"clock"
,
NULL
);
if
(
!
d
)
return
-
ENOMEM
;
clk_debugfs_root
=
d
;
list_for_each_entry
(
c
,
&
clock_list
,
node
)
{
err
=
clk_debugfs_register
(
c
);
if
(
err
)
goto
err_out
;
}
return
0
;
err_out:
debugfs_remove_recursive
(
clk_debugfs_root
);
return
err
;
}
late_initcall
(
clk_debugfs_init
);
arch/sh/kernel/cpu/sh4/clock-sh4-202.c
浏览文件 @
c5eb5b37
...
...
@@ -12,9 +12,10 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
#define CPG2_FRQCR3 0xfe0a0018
...
...
@@ -45,7 +46,6 @@ static struct clk_ops sh4202_emi_clk_ops = {
};
static
struct
clk
sh4202_emi_clk
=
{
.
name
=
"emi_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
sh4202_emi_clk_ops
,
};
...
...
@@ -61,7 +61,6 @@ static struct clk_ops sh4202_femi_clk_ops = {
};
static
struct
clk
sh4202_femi_clk
=
{
.
name
=
"femi_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
sh4202_femi_clk_ops
,
};
...
...
@@ -139,7 +138,6 @@ static struct clk_ops sh4202_shoc_clk_ops = {
};
static
struct
clk
sh4202_shoc_clk
=
{
.
name
=
"shoc_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
sh4202_shoc_clk_ops
,
};
...
...
@@ -150,6 +148,15 @@ static struct clk *sh4202_onchip_clocks[] = {
&
sh4202_shoc_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"emi_clk"
,
&
sh4202_emi_clk
),
CLKDEV_CON_ID
(
"femi_clk"
,
&
sh4202_femi_clk
),
CLKDEV_CON_ID
(
"shoc_clk"
,
&
sh4202_shoc_clk
),
};
int
__init
arch_clk_init
(
void
)
{
struct
clk
*
clk
;
...
...
@@ -167,5 +174,7 @@ int __init arch_clk_init(void)
clk_put
(
clk
);
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-sh7343.c
浏览文件 @
c5eb5b37
...
...
@@ -37,8 +37,6 @@
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static
struct
clk
r_clk
=
{
.
name
=
"rclk"
,
.
id
=
-
1
,
.
rate
=
32768
,
};
...
...
@@ -47,8 +45,6 @@ static struct clk r_clk = {
* from the platform code.
*/
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -70,8 +66,6 @@ static struct clk_ops dll_clk_ops = {
};
static
struct
clk
dll_clk
=
{
.
name
=
"dll_clk"
,
.
id
=
-
1
,
.
ops
=
&
dll_clk_ops
,
.
parent
=
&
r_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -92,8 +86,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
...
...
@@ -122,18 +114,18 @@ static struct clk_div4_table div4_table = {
enum
{
DIV4_I
,
DIV4_U
,
DIV4_SH
,
DIV4_B
,
DIV4_B3
,
DIV4_P
,
DIV4_SIUA
,
DIV4_SIUB
,
DIV4_NR
};
#define DIV4(_
str, _
reg, _bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, _reg, _bit, _mask, _flags)
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
FRQCR
,
20
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
"umem_clk"
,
FRQCR
,
16
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
FRQCR
,
12
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
FRQCR
,
8
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
"b3_clk"
,
FRQCR
,
4
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
FRQCR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUA
]
=
DIV4
(
"siua_clk"
,
SCLKACR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
"siub_clk"
,
SCLKBCR
,
0
,
0x1fff
,
0
),
[
DIV4_I
]
=
DIV4
(
FRQCR
,
20
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
FRQCR
,
16
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
FRQCR
,
12
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
FRQCR
,
8
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
FRQCR
,
4
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
FRQCR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUA
]
=
DIV4
(
SCLKACR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
SCLKBCR
,
0
,
0x1fff
,
0
),
};
enum
{
DIV6_V
,
DIV6_NR
};
...
...
@@ -142,61 +134,148 @@ struct clk div6_clks[DIV6_NR] = {
[
DIV6_V
]
=
SH_CLK_DIV6
(
&
pll_clk
,
VCLKCR
,
0
),
};
#define MSTP(_str, _parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
static
struct
clk
mstp_clks
[]
=
{
MSTP
(
"tlb0"
,
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
31
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"ic0"
,
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
30
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"oc0"
,
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
29
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"uram0"
,
&
div4_clks
[
DIV4_U
],
MSTPCR0
,
28
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"xymem0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR0
,
26
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"intc3"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
23
,
0
),
MSTP
(
"intc0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
22
,
0
),
MSTP
(
"dmac0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
MSTP
(
"sh0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
MSTP
(
"hudi0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
19
,
0
),
MSTP
(
"ubc0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
MSTP
(
"tmu_fck"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
15
,
0
),
MSTP
(
"cmt_fck"
,
&
r_clk
,
MSTPCR0
,
14
,
0
),
MSTP
(
"rwdt0"
,
&
r_clk
,
MSTPCR0
,
13
,
0
),
MSTP
(
"mfi0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
11
,
0
),
MSTP
(
"flctl0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
10
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
7
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
6
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
2
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
5
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
3
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
4
,
0
),
MSTP
(
"sio0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
3
,
0
),
MSTP
(
"siof0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
MSTP
(
"siof1"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
1
,
0
),
MSTP
(
"i2c0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR1
,
9
,
0
),
MSTP
(
"i2c1"
,
&
div4_clks
[
DIV4_P
],
MSTPCR1
,
8
,
0
),
MSTP
(
"tpu0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
25
,
0
),
MSTP
(
"irda0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
24
,
0
),
MSTP
(
"sdhi0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
18
,
0
),
MSTP
(
"mmcif0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
17
,
0
),
MSTP
(
"sim0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
16
,
0
),
MSTP
(
"keysc0"
,
&
r_clk
,
MSTPCR2
,
14
,
0
),
MSTP
(
"tsif0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
13
,
0
),
MSTP
(
"s3d40"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
12
,
0
),
MSTP
(
"usbf0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
11
,
0
),
MSTP
(
"siu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
8
,
0
),
MSTP
(
"jpu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
6
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"vou0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
5
,
0
),
MSTP
(
"beu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
4
,
0
),
MSTP
(
"ceu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
3
,
0
),
MSTP
(
"veu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
2
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"vpu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
1
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"lcdc0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
0
,
0
),
#define MSTP(_parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
enum
{
MSTP031
,
MSTP030
,
MSTP029
,
MSTP028
,
MSTP026
,
MSTP023
,
MSTP022
,
MSTP021
,
MSTP020
,
MSTP019
,
MSTP018
,
MSTP017
,
MSTP016
,
MSTP015
,
MSTP014
,
MSTP013
,
MSTP012
,
MSTP011
,
MSTP010
,
MSTP007
,
MSTP006
,
MSTP005
,
MSTP004
,
MSTP003
,
MSTP002
,
MSTP001
,
MSTP109
,
MSTP108
,
MSTP100
,
MSTP225
,
MSTP224
,
MSTP218
,
MSTP217
,
MSTP216
,
MSTP214
,
MSTP213
,
MSTP212
,
MSTP211
,
MSTP208
,
MSTP206
,
MSTP205
,
MSTP204
,
MSTP203
,
MSTP202
,
MSTP201
,
MSTP200
,
MSTP_NR
};
static
struct
clk
mstp_clks
[
MSTP_NR
]
=
{
[
MSTP031
]
=
MSTP
(
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
31
,
CLK_ENABLE_ON_INIT
),
[
MSTP030
]
=
MSTP
(
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
30
,
CLK_ENABLE_ON_INIT
),
[
MSTP029
]
=
MSTP
(
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
29
,
CLK_ENABLE_ON_INIT
),
[
MSTP028
]
=
MSTP
(
&
div4_clks
[
DIV4_U
],
MSTPCR0
,
28
,
CLK_ENABLE_ON_INIT
),
[
MSTP026
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR0
,
26
,
CLK_ENABLE_ON_INIT
),
[
MSTP023
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
23
,
0
),
[
MSTP022
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
22
,
0
),
[
MSTP021
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
[
MSTP020
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
[
MSTP019
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
19
,
0
),
[
MSTP017
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
[
MSTP015
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
15
,
0
),
[
MSTP014
]
=
MSTP
(
&
r_clk
,
MSTPCR0
,
14
,
0
),
[
MSTP013
]
=
MSTP
(
&
r_clk
,
MSTPCR0
,
13
,
0
),
[
MSTP011
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
11
,
0
),
[
MSTP010
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
10
,
0
),
[
MSTP007
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
7
,
0
),
[
MSTP006
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
6
,
0
),
[
MSTP005
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
5
,
0
),
[
MSTP004
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
4
,
0
),
[
MSTP003
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
3
,
0
),
[
MSTP002
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
[
MSTP001
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
1
,
0
),
[
MSTP109
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR1
,
9
,
0
),
[
MSTP108
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR1
,
8
,
0
),
[
MSTP225
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
25
,
0
),
[
MSTP224
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
24
,
0
),
[
MSTP218
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
18
,
0
),
[
MSTP217
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
17
,
0
),
[
MSTP216
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
16
,
0
),
[
MSTP214
]
=
MSTP
(
&
r_clk
,
MSTPCR2
,
14
,
0
),
[
MSTP213
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
13
,
0
),
[
MSTP212
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
12
,
0
),
[
MSTP211
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
11
,
0
),
[
MSTP208
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
8
,
0
),
[
MSTP206
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
6
,
CLK_ENABLE_ON_INIT
),
[
MSTP205
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
5
,
0
),
[
MSTP204
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
4
,
0
),
[
MSTP203
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
3
,
0
),
[
MSTP202
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
2
,
CLK_ENABLE_ON_INIT
),
[
MSTP201
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
1
,
CLK_ENABLE_ON_INIT
),
[
MSTP200
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
0
,
0
),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"rclk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"dll_clk"
,
&
dll_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
CLKDEV_CON_ID
(
"umem_clk"
,
&
div4_clks
[
DIV4_U
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"b3_clk"
,
&
div4_clks
[
DIV4_B3
]),
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"siua_clk"
,
&
div4_clks
[
DIV4_SIUA
]),
CLKDEV_CON_ID
(
"siub_clk"
,
&
div4_clks
[
DIV4_SIUB
]),
/* DIV6 clocks */
CLKDEV_CON_ID
(
"video_clk"
,
&
div6_clks
[
DIV6_V
]),
/* MSTP32 clocks */
CLKDEV_CON_ID
(
"tlb0"
,
&
mstp_clks
[
MSTP031
]),
CLKDEV_CON_ID
(
"ic0"
,
&
mstp_clks
[
MSTP030
]),
CLKDEV_CON_ID
(
"oc0"
,
&
mstp_clks
[
MSTP029
]),
CLKDEV_CON_ID
(
"uram0"
,
&
mstp_clks
[
MSTP028
]),
CLKDEV_CON_ID
(
"xymem0"
,
&
mstp_clks
[
MSTP026
]),
CLKDEV_CON_ID
(
"intc3"
,
&
mstp_clks
[
MSTP023
]),
CLKDEV_CON_ID
(
"intc0"
,
&
mstp_clks
[
MSTP022
]),
CLKDEV_CON_ID
(
"dmac0"
,
&
mstp_clks
[
MSTP021
]),
CLKDEV_CON_ID
(
"sh0"
,
&
mstp_clks
[
MSTP020
]),
CLKDEV_CON_ID
(
"hudi0"
,
&
mstp_clks
[
MSTP019
]),
CLKDEV_CON_ID
(
"ubc0"
,
&
mstp_clks
[
MSTP017
]),
CLKDEV_CON_ID
(
"tmu_fck"
,
&
mstp_clks
[
MSTP015
]),
CLKDEV_CON_ID
(
"cmt_fck"
,
&
mstp_clks
[
MSTP014
]),
CLKDEV_CON_ID
(
"rwdt0"
,
&
mstp_clks
[
MSTP013
]),
CLKDEV_CON_ID
(
"mfi0"
,
&
mstp_clks
[
MSTP011
]),
CLKDEV_CON_ID
(
"flctl0"
,
&
mstp_clks
[
MSTP010
]),
{
/* SCIF0 */
.
dev_id
=
"sh-sci.0"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP007
],
},
{
/* SCIF1 */
.
dev_id
=
"sh-sci.1"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP006
],
},
{
/* SCIF2 */
.
dev_id
=
"sh-sci.2"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP005
],
},
{
/* SCIF3 */
.
dev_id
=
"sh-sci.3"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP004
],
},
CLKDEV_CON_ID
(
"sio0"
,
&
mstp_clks
[
MSTP003
]),
CLKDEV_CON_ID
(
"siof0"
,
&
mstp_clks
[
MSTP002
]),
CLKDEV_CON_ID
(
"siof1"
,
&
mstp_clks
[
MSTP001
]),
CLKDEV_CON_ID
(
"i2c0"
,
&
mstp_clks
[
MSTP109
]),
CLKDEV_CON_ID
(
"i2c1"
,
&
mstp_clks
[
MSTP108
]),
CLKDEV_CON_ID
(
"tpu0"
,
&
mstp_clks
[
MSTP225
]),
CLKDEV_CON_ID
(
"irda0"
,
&
mstp_clks
[
MSTP224
]),
CLKDEV_CON_ID
(
"sdhi0"
,
&
mstp_clks
[
MSTP218
]),
CLKDEV_CON_ID
(
"mmcif0"
,
&
mstp_clks
[
MSTP217
]),
CLKDEV_CON_ID
(
"sim0"
,
&
mstp_clks
[
MSTP216
]),
CLKDEV_CON_ID
(
"keysc0"
,
&
mstp_clks
[
MSTP214
]),
CLKDEV_CON_ID
(
"tsif0"
,
&
mstp_clks
[
MSTP213
]),
CLKDEV_CON_ID
(
"s3d40"
,
&
mstp_clks
[
MSTP212
]),
CLKDEV_CON_ID
(
"usbf0"
,
&
mstp_clks
[
MSTP211
]),
CLKDEV_CON_ID
(
"siu0"
,
&
mstp_clks
[
MSTP208
]),
CLKDEV_CON_ID
(
"jpu0"
,
&
mstp_clks
[
MSTP206
]),
CLKDEV_CON_ID
(
"vou0"
,
&
mstp_clks
[
MSTP205
]),
CLKDEV_CON_ID
(
"beu0"
,
&
mstp_clks
[
MSTP204
]),
CLKDEV_CON_ID
(
"ceu0"
,
&
mstp_clks
[
MSTP203
]),
CLKDEV_CON_ID
(
"veu0"
,
&
mstp_clks
[
MSTP202
]),
CLKDEV_CON_ID
(
"vpu0"
,
&
mstp_clks
[
MSTP201
]),
CLKDEV_CON_ID
(
"lcdc0"
,
&
mstp_clks
[
MSTP200
]),
};
int
__init
arch_clk_init
(
void
)
...
...
@@ -221,7 +300,7 @@ int __init arch_clk_init(void)
ret
=
sh_clk_div6_register
(
div6_clks
,
DIV6_NR
);
if
(
!
ret
)
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
ARRAY_SIZE
(
mstp_clks
)
);
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
MSTP_NR
);
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-sh7366.c
浏览文件 @
c5eb5b37
...
...
@@ -37,8 +37,6 @@
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static
struct
clk
r_clk
=
{
.
name
=
"rclk"
,
.
id
=
-
1
,
.
rate
=
32768
,
};
...
...
@@ -47,8 +45,6 @@ static struct clk r_clk = {
* from the platform code.
*/
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -70,8 +66,6 @@ static struct clk_ops dll_clk_ops = {
};
static
struct
clk
dll_clk
=
{
.
name
=
"dll_clk"
,
.
id
=
-
1
,
.
ops
=
&
dll_clk_ops
,
.
parent
=
&
r_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -95,8 +89,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
...
...
@@ -125,18 +117,18 @@ static struct clk_div4_table div4_table = {
enum
{
DIV4_I
,
DIV4_U
,
DIV4_SH
,
DIV4_B
,
DIV4_B3
,
DIV4_P
,
DIV4_SIUA
,
DIV4_SIUB
,
DIV4_NR
};
#define DIV4(_
str, _
reg, _bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, _reg, _bit, _mask, _flags)
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
FRQCR
,
20
,
0x1fef
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
"umem_clk"
,
FRQCR
,
16
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
FRQCR
,
12
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
FRQCR
,
8
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
"b3_clk"
,
FRQCR
,
4
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
FRQCR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUA
]
=
DIV4
(
"siua_clk"
,
SCLKACR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
"siub_clk"
,
SCLKBCR
,
0
,
0x1fff
,
0
),
[
DIV4_I
]
=
DIV4
(
FRQCR
,
20
,
0x1fef
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
FRQCR
,
16
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
FRQCR
,
12
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
FRQCR
,
8
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
FRQCR
,
4
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
FRQCR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUA
]
=
DIV4
(
SCLKACR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
SCLKBCR
,
0
,
0x1fff
,
0
),
};
enum
{
DIV6_V
,
DIV6_NR
};
...
...
@@ -145,58 +137,134 @@ struct clk div6_clks[DIV6_NR] = {
[
DIV6_V
]
=
SH_CLK_DIV6
(
&
pll_clk
,
VCLKCR
,
0
),
};
#define MSTP(_
str, _
parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_
str, -1, _
parent, _reg, _bit, _flags)
#define MSTP(_parent, _reg, _bit, _flags) \
SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
static
struct
clk
mstp_clks
[]
=
{
enum
{
MSTP031
,
MSTP030
,
MSTP029
,
MSTP028
,
MSTP026
,
MSTP023
,
MSTP022
,
MSTP021
,
MSTP020
,
MSTP019
,
MSTP018
,
MSTP017
,
MSTP016
,
MSTP015
,
MSTP014
,
MSTP013
,
MSTP012
,
MSTP011
,
MSTP010
,
MSTP007
,
MSTP006
,
MSTP005
,
MSTP002
,
MSTP001
,
MSTP109
,
MSTP100
,
MSTP227
,
MSTP226
,
MSTP224
,
MSTP223
,
MSTP222
,
MSTP218
,
MSTP217
,
MSTP211
,
MSTP207
,
MSTP205
,
MSTP204
,
MSTP203
,
MSTP202
,
MSTP201
,
MSTP200
,
MSTP_NR
};
static
struct
clk
mstp_clks
[
MSTP_NR
]
=
{
/* See page 52 of Datasheet V0.40: Overview -> Block Diagram */
MSTP
(
"tlb0"
,
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
31
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"ic0"
,
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
30
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"oc0"
,
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
29
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"rsmem0"
,
&
div4_clks
[
DIV4_SH
],
MSTPCR0
,
28
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"xymem0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR0
,
26
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"intc3"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
23
,
0
),
MSTP
(
"intc0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
22
,
0
),
MSTP
(
"dmac0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
MSTP
(
"sh0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
MSTP
(
"hudi0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
19
,
0
),
MSTP
(
"ubc0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
MSTP
(
"tmu_fck"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
15
,
0
),
MSTP
(
"cmt_fck"
,
&
r_clk
,
MSTPCR0
,
14
,
0
),
MSTP
(
"rwdt0"
,
&
r_clk
,
MSTPCR0
,
13
,
0
),
MSTP
(
"mfi0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
11
,
0
),
MSTP
(
"flctl0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
10
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
7
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
6
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
2
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
5
,
0
),
MSTP
(
"msiof0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
MSTP
(
"sbr0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
1
,
0
),
MSTP
(
"i2c0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR1
,
9
,
0
),
MSTP
(
"icb0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
27
,
0
),
MSTP
(
"meram0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
26
,
0
),
MSTP
(
"dacy1"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
24
,
0
),
MSTP
(
"dacy0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
23
,
0
),
MSTP
(
"tsif0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
22
,
0
),
MSTP
(
"sdhi0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
18
,
0
),
MSTP
(
"mmcif0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
17
,
0
),
MSTP
(
"usbf0"
,
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
11
,
0
),
MSTP
(
"siu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
9
,
0
),
MSTP
(
"veu1"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
7
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"vou0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
5
,
0
),
MSTP
(
"beu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
4
,
0
),
MSTP
(
"ceu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
3
,
0
),
MSTP
(
"veu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
2
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"vpu0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
1
,
CLK_ENABLE_ON_INIT
),
MSTP
(
"lcdc0"
,
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
0
,
0
),
[
MSTP031
]
=
MSTP
(
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
31
,
CLK_ENABLE_ON_INIT
),
[
MSTP030
]
=
MSTP
(
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
30
,
CLK_ENABLE_ON_INIT
),
[
MSTP029
]
=
MSTP
(
&
div4_clks
[
DIV4_I
],
MSTPCR0
,
29
,
CLK_ENABLE_ON_INIT
),
[
MSTP028
]
=
MSTP
(
&
div4_clks
[
DIV4_SH
],
MSTPCR0
,
28
,
CLK_ENABLE_ON_INIT
),
[
MSTP026
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR0
,
26
,
CLK_ENABLE_ON_INIT
),
[
MSTP023
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
23
,
0
),
[
MSTP022
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
22
,
0
),
[
MSTP021
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
[
MSTP020
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
[
MSTP019
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
19
,
0
),
[
MSTP017
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
[
MSTP015
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
15
,
0
),
[
MSTP014
]
=
MSTP
(
&
r_clk
,
MSTPCR0
,
14
,
0
),
[
MSTP013
]
=
MSTP
(
&
r_clk
,
MSTPCR0
,
13
,
0
),
[
MSTP011
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
11
,
0
),
[
MSTP010
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
10
,
0
),
[
MSTP007
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
7
,
0
),
[
MSTP006
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
6
,
0
),
[
MSTP005
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
5
,
0
),
[
MSTP002
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
[
MSTP001
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
1
,
0
),
[
MSTP109
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR1
,
9
,
0
),
[
MSTP227
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
27
,
0
),
[
MSTP226
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
26
,
0
),
[
MSTP224
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
24
,
0
),
[
MSTP223
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
23
,
0
),
[
MSTP222
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
22
,
0
),
[
MSTP218
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
18
,
0
),
[
MSTP217
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
17
,
0
),
[
MSTP211
]
=
MSTP
(
&
div4_clks
[
DIV4_P
],
MSTPCR2
,
11
,
0
),
[
MSTP207
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
7
,
CLK_ENABLE_ON_INIT
),
[
MSTP205
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
5
,
0
),
[
MSTP204
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
4
,
0
),
[
MSTP203
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
3
,
0
),
[
MSTP202
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
2
,
CLK_ENABLE_ON_INIT
),
[
MSTP201
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
1
,
CLK_ENABLE_ON_INIT
),
[
MSTP200
]
=
MSTP
(
&
div4_clks
[
DIV4_B
],
MSTPCR2
,
0
,
0
),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"rclk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"dll_clk"
,
&
dll_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
CLKDEV_CON_ID
(
"umem_clk"
,
&
div4_clks
[
DIV4_U
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"b3_clk"
,
&
div4_clks
[
DIV4_B3
]),
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"siua_clk"
,
&
div4_clks
[
DIV4_SIUA
]),
CLKDEV_CON_ID
(
"siub_clk"
,
&
div4_clks
[
DIV4_SIUB
]),
/* DIV6 clocks */
CLKDEV_CON_ID
(
"video_clk"
,
&
div6_clks
[
DIV6_V
]),
/* MSTP32 clocks */
CLKDEV_CON_ID
(
"tlb0"
,
&
mstp_clks
[
MSTP031
]),
CLKDEV_CON_ID
(
"ic0"
,
&
mstp_clks
[
MSTP030
]),
CLKDEV_CON_ID
(
"oc0"
,
&
mstp_clks
[
MSTP029
]),
CLKDEV_CON_ID
(
"rsmem0"
,
&
mstp_clks
[
MSTP028
]),
CLKDEV_CON_ID
(
"xymem0"
,
&
mstp_clks
[
MSTP026
]),
CLKDEV_CON_ID
(
"intc3"
,
&
mstp_clks
[
MSTP023
]),
CLKDEV_CON_ID
(
"intc0"
,
&
mstp_clks
[
MSTP022
]),
CLKDEV_CON_ID
(
"dmac0"
,
&
mstp_clks
[
MSTP021
]),
CLKDEV_CON_ID
(
"sh0"
,
&
mstp_clks
[
MSTP020
]),
CLKDEV_CON_ID
(
"hudi0"
,
&
mstp_clks
[
MSTP019
]),
CLKDEV_CON_ID
(
"ubc0"
,
&
mstp_clks
[
MSTP017
]),
CLKDEV_CON_ID
(
"tmu_fck"
,
&
mstp_clks
[
MSTP015
]),
CLKDEV_CON_ID
(
"cmt_fck"
,
&
mstp_clks
[
MSTP014
]),
CLKDEV_CON_ID
(
"rwdt0"
,
&
mstp_clks
[
MSTP013
]),
CLKDEV_CON_ID
(
"mfi0"
,
&
mstp_clks
[
MSTP011
]),
CLKDEV_CON_ID
(
"flctl0"
,
&
mstp_clks
[
MSTP010
]),
{
/* SCIF0 */
.
dev_id
=
"sh-sci.0"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP007
],
},
{
/* SCIF1 */
.
dev_id
=
"sh-sci.1"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP006
],
},
{
/* SCIF2 */
.
dev_id
=
"sh-sci.2"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP005
],
},
CLKDEV_CON_ID
(
"msiof0"
,
&
mstp_clks
[
MSTP002
]),
CLKDEV_CON_ID
(
"sbr0"
,
&
mstp_clks
[
MSTP001
]),
CLKDEV_CON_ID
(
"i2c0"
,
&
mstp_clks
[
MSTP109
]),
CLKDEV_CON_ID
(
"icb0"
,
&
mstp_clks
[
MSTP227
]),
CLKDEV_CON_ID
(
"meram0"
,
&
mstp_clks
[
MSTP226
]),
CLKDEV_CON_ID
(
"dacy1"
,
&
mstp_clks
[
MSTP224
]),
CLKDEV_CON_ID
(
"dacy0"
,
&
mstp_clks
[
MSTP223
]),
CLKDEV_CON_ID
(
"tsif0"
,
&
mstp_clks
[
MSTP222
]),
CLKDEV_CON_ID
(
"sdhi0"
,
&
mstp_clks
[
MSTP218
]),
CLKDEV_CON_ID
(
"mmcif0"
,
&
mstp_clks
[
MSTP217
]),
CLKDEV_CON_ID
(
"usbf0"
,
&
mstp_clks
[
MSTP211
]),
CLKDEV_CON_ID
(
"veu1"
,
&
mstp_clks
[
MSTP207
]),
CLKDEV_CON_ID
(
"vou0"
,
&
mstp_clks
[
MSTP205
]),
CLKDEV_CON_ID
(
"beu0"
,
&
mstp_clks
[
MSTP204
]),
CLKDEV_CON_ID
(
"ceu0"
,
&
mstp_clks
[
MSTP203
]),
CLKDEV_CON_ID
(
"veu0"
,
&
mstp_clks
[
MSTP202
]),
CLKDEV_CON_ID
(
"vpu0"
,
&
mstp_clks
[
MSTP201
]),
CLKDEV_CON_ID
(
"lcdc0"
,
&
mstp_clks
[
MSTP200
]),
};
int
__init
arch_clk_init
(
void
)
...
...
@@ -221,7 +289,7 @@ int __init arch_clk_init(void)
ret
=
sh_clk_div6_register
(
div6_clks
,
DIV6_NR
);
if
(
!
ret
)
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
ARRAY_SIZE
(
mstp_clks
)
);
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
MSTP_NR
);
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-sh7722.c
浏览文件 @
c5eb5b37
...
...
@@ -37,8 +37,6 @@
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static
struct
clk
r_clk
=
{
.
name
=
"rclk"
,
.
id
=
-
1
,
.
rate
=
32768
,
};
...
...
@@ -47,8 +45,6 @@ static struct clk r_clk = {
* from the platform code.
*/
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -70,8 +66,6 @@ static struct clk_ops dll_clk_ops = {
};
static
struct
clk
dll_clk
=
{
.
name
=
"dll_clk"
,
.
id
=
-
1
,
.
ops
=
&
dll_clk_ops
,
.
parent
=
&
r_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -95,8 +89,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
...
...
@@ -122,31 +114,31 @@ static struct clk_div4_table div4_table = {
.
div_mult_table
=
&
div4_div_mult_table
,
};
#define DIV4(_
str, _
reg, _bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, _reg, _bit, _mask, _flags)
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
enum
{
DIV4_I
,
DIV4_U
,
DIV4_SH
,
DIV4_B
,
DIV4_B3
,
DIV4_P
,
DIV4_NR
};
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
FRQCR
,
20
,
0x1fef
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
"umem_clk"
,
FRQCR
,
16
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
FRQCR
,
12
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
FRQCR
,
8
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
"b3_clk"
,
FRQCR
,
4
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
FRQCR
,
0
,
0x1fff
,
0
),
[
DIV4_I
]
=
DIV4
(
FRQCR
,
20
,
0x1fef
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
FRQCR
,
16
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
FRQCR
,
12
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
FRQCR
,
8
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
FRQCR
,
4
,
0x1fff
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
FRQCR
,
0
,
0x1fff
,
0
),
};
enum
{
DIV4_IRDA
,
DIV4_ENABLE_NR
};
struct
clk
div4_enable_clks
[
DIV4_ENABLE_NR
]
=
{
[
DIV4_IRDA
]
=
DIV4
(
"irda_clk"
,
IRDACLKCR
,
0
,
0x1fff
,
0
),
[
DIV4_IRDA
]
=
DIV4
(
IRDACLKCR
,
0
,
0x1fff
,
0
),
};
enum
{
DIV4_SIUA
,
DIV4_SIUB
,
DIV4_REPARENT_NR
};
struct
clk
div4_reparent_clks
[
DIV4_REPARENT_NR
]
=
{
[
DIV4_SIUA
]
=
DIV4
(
"siua_clk"
,
SCLKACR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
"siub_clk"
,
SCLKBCR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUA
]
=
DIV4
(
SCLKACR
,
0
,
0x1fff
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
SCLKBCR
,
0
,
0x1fff
,
0
),
};
enum
{
DIV6_V
,
DIV6_NR
};
...
...
@@ -186,6 +178,23 @@ static struct clk mstp_clks[HWBLK_NR] = {
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"rclk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"dll_clk"
,
&
dll_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
CLKDEV_CON_ID
(
"umem_clk"
,
&
div4_clks
[
DIV4_U
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"b3_clk"
,
&
div4_clks
[
DIV4_B3
]),
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"irda_clk"
,
&
div4_enable_clks
[
DIV4_IRDA
]),
CLKDEV_CON_ID
(
"siua_clk"
,
&
div4_reparent_clks
[
DIV4_SIUA
]),
CLKDEV_CON_ID
(
"siub_clk"
,
&
div4_reparent_clks
[
DIV4_SIUB
]),
/* DIV6 clocks */
CLKDEV_CON_ID
(
"video_clk"
,
&
div6_clks
[
DIV6_V
]),
...
...
arch/sh/kernel/cpu/sh4a/clock-sh7723.c
浏览文件 @
c5eb5b37
...
...
@@ -38,8 +38,6 @@
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static
struct
clk
r_clk
=
{
.
name
=
"rclk"
,
.
id
=
-
1
,
.
rate
=
32768
,
};
...
...
@@ -48,8 +46,6 @@ static struct clk r_clk = {
* from the platform code.
*/
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -71,8 +67,6 @@ static struct clk_ops dll_clk_ops = {
};
static
struct
clk
dll_clk
=
{
.
name
=
"dll_clk"
,
.
id
=
-
1
,
.
ops
=
&
dll_clk_ops
,
.
parent
=
&
r_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -96,8 +90,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
...
...
@@ -125,29 +117,29 @@ static struct clk_div4_table div4_table = {
enum
{
DIV4_I
,
DIV4_U
,
DIV4_SH
,
DIV4_B
,
DIV4_B3
,
DIV4_P
,
DIV4_NR
};
#define DIV4(_
str, _
reg, _bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, _reg, _bit, _mask, _flags)
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
FRQCR
,
20
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
"umem_clk"
,
FRQCR
,
16
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
FRQCR
,
12
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
FRQCR
,
8
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
"b3_clk"
,
FRQCR
,
4
,
0x0db4
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
FRQCR
,
0
,
0x0dbf
,
0
),
[
DIV4_I
]
=
DIV4
(
FRQCR
,
20
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
FRQCR
,
16
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
FRQCR
,
12
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
FRQCR
,
8
,
0x0dbf
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B3
]
=
DIV4
(
FRQCR
,
4
,
0x0db4
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
FRQCR
,
0
,
0x0dbf
,
0
),
};
enum
{
DIV4_IRDA
,
DIV4_ENABLE_NR
};
struct
clk
div4_enable_clks
[
DIV4_ENABLE_NR
]
=
{
[
DIV4_IRDA
]
=
DIV4
(
"irda_clk"
,
IRDACLKCR
,
0
,
0x0dbf
,
0
),
[
DIV4_IRDA
]
=
DIV4
(
IRDACLKCR
,
0
,
0x0dbf
,
0
),
};
enum
{
DIV4_SIUA
,
DIV4_SIUB
,
DIV4_REPARENT_NR
};
struct
clk
div4_reparent_clks
[
DIV4_REPARENT_NR
]
=
{
[
DIV4_SIUA
]
=
DIV4
(
"siua_clk"
,
SCLKACR
,
0
,
0x0dbf
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
"siub_clk"
,
SCLKBCR
,
0
,
0x0dbf
,
0
),
[
DIV4_SIUA
]
=
DIV4
(
SCLKACR
,
0
,
0x0dbf
,
0
),
[
DIV4_SIUB
]
=
DIV4
(
SCLKBCR
,
0
,
0x0dbf
,
0
),
};
enum
{
DIV6_V
,
DIV6_NR
};
...
...
@@ -211,6 +203,23 @@ static struct clk mstp_clks[] = {
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"rclk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"dll_clk"
,
&
dll_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
CLKDEV_CON_ID
(
"umem_clk"
,
&
div4_clks
[
DIV4_U
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"b3_clk"
,
&
div4_clks
[
DIV4_B3
]),
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"irda_clk"
,
&
div4_enable_clks
[
DIV4_IRDA
]),
CLKDEV_CON_ID
(
"siua_clk"
,
&
div4_reparent_clks
[
DIV4_SIUA
]),
CLKDEV_CON_ID
(
"siub_clk"
,
&
div4_reparent_clks
[
DIV4_SIUB
]),
/* DIV6 clocks */
CLKDEV_CON_ID
(
"video_clk"
,
&
div6_clks
[
DIV6_V
]),
...
...
arch/sh/kernel/cpu/sh4a/clock-sh7724.c
浏览文件 @
c5eb5b37
...
...
@@ -41,8 +41,6 @@
/* Fixed 32 KHz root clock for RTC and Power Management purposes */
static
struct
clk
r_clk
=
{
.
name
=
"rclk"
,
.
id
=
-
1
,
.
rate
=
32768
,
};
...
...
@@ -51,8 +49,6 @@ static struct clk r_clk = {
* from the platform code.
*/
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -76,8 +72,6 @@ static struct clk_ops fll_clk_ops = {
};
static
struct
clk
fll_clk
=
{
.
name
=
"fll_clk"
,
.
id
=
-
1
,
.
ops
=
&
fll_clk_ops
,
.
parent
=
&
r_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -98,8 +92,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
flags
=
CLK_ENABLE_ON_INIT
,
};
...
...
@@ -115,8 +107,6 @@ static struct clk_ops div3_clk_ops = {
};
static
struct
clk
div3_clk
=
{
.
name
=
"div3_clk"
,
.
id
=
-
1
,
.
ops
=
&
div3_clk_ops
,
.
parent
=
&
pll_clk
,
};
...
...
@@ -153,15 +143,15 @@ static struct clk_div4_table div4_table = {
enum
{
DIV4_I
,
DIV4_SH
,
DIV4_B
,
DIV4_P
,
DIV4_M1
,
DIV4_NR
};
#define DIV4(_
str, _
reg, _bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, _reg, _bit, _mask, _flags)
#define DIV4(_reg, _bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags)
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
FRQCRA
,
20
,
0x2f7d
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
FRQCRA
,
12
,
0x2f7c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
FRQCRA
,
8
,
0x2f7c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
FRQCRA
,
0
,
0x2f7c
,
0
),
[
DIV4_M1
]
=
DIV4
(
"vpu_clk"
,
FRQCRB
,
4
,
0x2f7c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_I
]
=
DIV4
(
FRQCRA
,
20
,
0x2f7d
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
FRQCRA
,
12
,
0x2f7c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
FRQCRA
,
8
,
0x2f7c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
FRQCRA
,
0
,
0x2f7c
,
0
),
[
DIV4_M1
]
=
DIV4
(
FRQCRB
,
4
,
0x2f7c
,
CLK_ENABLE_ON_INIT
),
};
enum
{
DIV6_V
,
DIV6_FA
,
DIV6_FB
,
DIV6_I
,
DIV6_S
,
DIV6_NR
};
...
...
@@ -234,6 +224,20 @@ static struct clk mstp_clks[HWBLK_NR] = {
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"rclk"
,
&
r_clk
),
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"fll_clk"
,
&
fll_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
CLKDEV_CON_ID
(
"div3_clk"
,
&
div3_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"vpu_clk"
,
&
div4_clks
[
DIV4_M1
]),
/* DIV6 clocks */
CLKDEV_CON_ID
(
"video_clk"
,
&
div6_clks
[
DIV6_V
]),
CLKDEV_CON_ID
(
"fsia_clk"
,
&
div6_clks
[
DIV6_FA
]),
...
...
arch/sh/kernel/cpu/sh4a/clock-sh7757.c
浏览文件 @
c5eb5b37
...
...
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
...
...
@@ -87,7 +88,6 @@ static struct clk_ops sh7757_shyway_clk_ops = {
};
static
struct
clk
sh7757_shyway_clk
=
{
.
name
=
"shyway_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
sh7757_shyway_clk_ops
,
};
...
...
@@ -100,6 +100,13 @@ static struct clk *sh7757_onchip_clocks[] = {
&
sh7757_shyway_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"shyway_clk"
,
&
sh7757_shyway_clk
),
};
static
int
__init
sh7757_clk_init
(
void
)
{
struct
clk
*
clk
=
clk_get
(
NULL
,
"master_clk"
);
...
...
@@ -123,6 +130,8 @@ static int __init sh7757_clk_init(void)
clk_put
(
clk
);
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
return
0
;
}
...
...
arch/sh/kernel/cpu/sh4a/clock-sh7763.c
浏览文件 @
c5eb5b37
...
...
@@ -12,6 +12,8 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
...
...
@@ -77,7 +79,6 @@ static struct clk_ops sh7763_shyway_clk_ops = {
};
static
struct
clk
sh7763_shyway_clk
=
{
.
name
=
"shyway_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
sh7763_shyway_clk_ops
,
};
...
...
@@ -90,6 +91,13 @@ static struct clk *sh7763_onchip_clocks[] = {
&
sh7763_shyway_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"shyway_clk"
,
&
sh7763_shyway_clk
),
};
int
__init
arch_clk_init
(
void
)
{
struct
clk
*
clk
;
...
...
@@ -107,5 +115,7 @@ int __init arch_clk_init(void)
clk_put
(
clk
);
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-sh7780.c
浏览文件 @
c5eb5b37
...
...
@@ -11,6 +11,8 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
...
...
@@ -83,7 +85,6 @@ static struct clk_ops sh7780_shyway_clk_ops = {
};
static
struct
clk
sh7780_shyway_clk
=
{
.
name
=
"shyway_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
sh7780_shyway_clk_ops
,
};
...
...
@@ -96,6 +97,13 @@ static struct clk *sh7780_onchip_clocks[] = {
&
sh7780_shyway_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"shyway_clk"
,
&
sh7780_shyway_clk
),
};
int
__init
arch_clk_init
(
void
)
{
struct
clk
*
clk
;
...
...
@@ -113,5 +121,7 @@ int __init arch_clk_init(void)
clk_put
(
clk
);
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-sh7785.c
浏览文件 @
c5eb5b37
...
...
@@ -24,8 +24,6 @@
* from the platform code.
*/
static
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -43,8 +41,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
parent
=
&
extal_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -70,82 +66,149 @@ static struct clk_div4_table div4_table = {
enum
{
DIV4_I
,
DIV4_U
,
DIV4_SH
,
DIV4_B
,
DIV4_DDR
,
DIV4_GA
,
DIV4_DU
,
DIV4_P
,
DIV4_NR
};
#define DIV4(_
str, _
bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, FRQMR1, _bit, _mask, _flags)
#define DIV4(_bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
0
,
0x0f80
,
0
),
[
DIV4_DU
]
=
DIV4
(
"du_clk"
,
4
,
0x0ff0
,
0
),
[
DIV4_GA
]
=
DIV4
(
"ga_clk"
,
8
,
0x0030
,
0
),
[
DIV4_DDR
]
=
DIV4
(
"ddr_clk"
,
12
,
0x000c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
16
,
0x0fe0
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
20
,
0x000c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
"umem_clk"
,
24
,
0x000c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
28
,
0x000e
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
0
,
0x0f80
,
0
),
[
DIV4_DU
]
=
DIV4
(
4
,
0x0ff0
,
0
),
[
DIV4_GA
]
=
DIV4
(
8
,
0x0030
,
0
),
[
DIV4_DDR
]
=
DIV4
(
12
,
0x000c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
16
,
0x0fe0
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
20
,
0x000c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_U
]
=
DIV4
(
24
,
0x000c
,
CLK_ENABLE_ON_INIT
),
[
DIV4_I
]
=
DIV4
(
28
,
0x000e
,
CLK_ENABLE_ON_INIT
),
};
#define MSTPCR0 0xffc80030
#define MSTPCR1 0xffc80034
static
struct
clk
mstp_clks
[]
=
{
enum
{
MSTP029
,
MSTP028
,
MSTP027
,
MSTP026
,
MSTP025
,
MSTP024
,
MSTP021
,
MSTP020
,
MSTP017
,
MSTP016
,
MSTP013
,
MSTP012
,
MSTP009
,
MSTP008
,
MSTP003
,
MSTP002
,
MSTP119
,
MSTP117
,
MSTP105
,
MSTP104
,
MSTP100
,
MSTP_NR
};
static
struct
clk
mstp_clks
[
MSTP_NR
]
=
{
/* MSTPCR0 */
SH_CLK_MSTP32
(
"sci_fck"
,
5
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
29
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
4
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
28
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
3
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
27
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
2
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
26
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
25
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
24
,
0
),
SH_CLK_MSTP32
(
"ssi_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
SH_CLK_MSTP32
(
"ssi_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
SH_CLK_MSTP32
(
"hac_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
SH_CLK_MSTP32
(
"hac_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
16
,
0
),
SH_CLK_MSTP32
(
"mmcif_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
13
,
0
),
SH_CLK_MSTP32
(
"flctl_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
12
,
0
),
SH_CLK_MSTP32
(
"tmu345_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
9
,
0
),
SH_CLK_MSTP32
(
"tmu012_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
8
,
0
),
SH_CLK_MSTP32
(
"siof_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
3
,
0
),
SH_CLK_MSTP32
(
"hspi_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
[
MSTP029
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
29
,
0
),
[
MSTP028
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
28
,
0
),
[
MSTP027
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
27
,
0
),
[
MSTP026
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
26
,
0
),
[
MSTP025
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
25
,
0
),
[
MSTP024
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
24
,
0
),
[
MSTP021
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
[
MSTP020
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
[
MSTP017
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
[
MSTP016
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
16
,
0
),
[
MSTP013
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
13
,
0
),
[
MSTP012
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
12
,
0
),
[
MSTP009
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
9
,
0
),
[
MSTP008
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
8
,
0
),
[
MSTP003
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
3
,
0
),
[
MSTP002
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
/* MSTPCR1 */
SH_CLK_MSTP32
(
"hudi_fck"
,
-
1
,
NULL
,
MSTPCR1
,
19
,
0
),
SH_CLK_MSTP32
(
"ubc_fck"
,
-
1
,
NULL
,
MSTPCR1
,
17
,
0
),
SH_CLK_MSTP32
(
"dmac_11_6_fck"
,
-
1
,
NULL
,
MSTPCR1
,
5
,
0
),
SH_CLK_MSTP32
(
"dmac_5_0_fck"
,
-
1
,
NULL
,
MSTPCR1
,
4
,
0
),
SH_CLK_MSTP32
(
"gdta_fck"
,
-
1
,
NULL
,
MSTPCR1
,
0
,
0
),
[
MSTP119
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
19
,
0
),
[
MSTP117
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
17
,
0
),
[
MSTP105
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
5
,
0
),
[
MSTP104
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
4
,
0
),
[
MSTP100
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
0
,
0
),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"du_clk"
,
&
div4_clks
[
DIV4_DU
]),
CLKDEV_CON_ID
(
"ga_clk"
,
&
div4_clks
[
DIV4_GA
]),
CLKDEV_CON_ID
(
"ddr_clk"
,
&
div4_clks
[
DIV4_DDR
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"umem_clk"
,
&
div4_clks
[
DIV4_U
]),
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
/* MSTP32 clocks */
{
/* SCIF5 */
.
dev_id
=
"sh-sci.5"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP029
],
},
{
/* SCIF4 */
.
dev_id
=
"sh-sci.4"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP028
],
},
{
/* SCIF3 */
.
dev_id
=
"sh-sci.3"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP027
],
},
{
/* SCIF2 */
.
dev_id
=
"sh-sci.2"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP026
],
},
{
/* SCIF1 */
.
dev_id
=
"sh-sci.1"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP025
],
},
{
/* SCIF0 */
.
dev_id
=
"sh-sci.0"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP024
],
},
CLKDEV_CON_ID
(
"ssi1_fck"
,
&
mstp_clks
[
MSTP021
]),
CLKDEV_CON_ID
(
"ssi0_fck"
,
&
mstp_clks
[
MSTP020
]),
CLKDEV_CON_ID
(
"hac1_fck"
,
&
mstp_clks
[
MSTP017
]),
CLKDEV_CON_ID
(
"hac0_fck"
,
&
mstp_clks
[
MSTP016
]),
CLKDEV_CON_ID
(
"mmcif_fck"
,
&
mstp_clks
[
MSTP013
]),
CLKDEV_CON_ID
(
"flctl_fck"
,
&
mstp_clks
[
MSTP012
]),
{
/* TMU0 */
.
dev_id
=
"sh_tmu.0"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
13
],
/* tmu012_fck */
.
clk
=
&
mstp_clks
[
MSTP008
],
},
{
/* TMU1 */
.
dev_id
=
"sh_tmu.1"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
13
],
.
clk
=
&
mstp_clks
[
MSTP008
],
},
{
/* TMU2 */
.
dev_id
=
"sh_tmu.2"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
13
],
.
clk
=
&
mstp_clks
[
MSTP008
],
},
{
/* TMU3 */
.
dev_id
=
"sh_tmu.3"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
12
],
/* tmu345_fck */
.
clk
=
&
mstp_clks
[
MSTP009
],
},
{
/* TMU4 */
.
dev_id
=
"sh_tmu.4"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
12
],
.
clk
=
&
mstp_clks
[
MSTP009
],
},
{
/* TMU5 */
.
dev_id
=
"sh_tmu.5"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
12
],
.
clk
=
&
mstp_clks
[
MSTP009
],
},
CLKDEV_CON_ID
(
"siof_fck"
,
&
mstp_clks
[
MSTP003
]),
CLKDEV_CON_ID
(
"hspi_fck"
,
&
mstp_clks
[
MSTP002
]),
CLKDEV_CON_ID
(
"hudi_fck"
,
&
mstp_clks
[
MSTP119
]),
CLKDEV_CON_ID
(
"ubc_fck"
,
&
mstp_clks
[
MSTP117
]),
CLKDEV_CON_ID
(
"dmac_11_6_fck"
,
&
mstp_clks
[
MSTP105
]),
CLKDEV_CON_ID
(
"dmac_5_0_fck"
,
&
mstp_clks
[
MSTP104
]),
CLKDEV_CON_ID
(
"gdta_fck"
,
&
mstp_clks
[
MSTP100
]),
};
int
__init
arch_clk_init
(
void
)
...
...
@@ -161,7 +224,7 @@ int __init arch_clk_init(void)
ret
=
sh_clk_div4_register
(
div4_clks
,
ARRAY_SIZE
(
div4_clks
),
&
div4_table
);
if
(
!
ret
)
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
ARRAY_SIZE
(
mstp_clks
)
);
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
MSTP_NR
);
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-sh7786.c
浏览文件 @
c5eb5b37
...
...
@@ -23,8 +23,6 @@
* from the platform code.
*/
static
struct
clk
extal_clk
=
{
.
name
=
"extal"
,
.
id
=
-
1
,
.
rate
=
33333333
,
};
...
...
@@ -46,8 +44,6 @@ static struct clk_ops pll_clk_ops = {
};
static
struct
clk
pll_clk
=
{
.
name
=
"pll_clk"
,
.
id
=
-
1
,
.
ops
=
&
pll_clk_ops
,
.
parent
=
&
extal_clk
,
.
flags
=
CLK_ENABLE_ON_INIT
,
...
...
@@ -72,118 +68,191 @@ static struct clk_div4_table div4_table = {
enum
{
DIV4_I
,
DIV4_SH
,
DIV4_B
,
DIV4_DDR
,
DIV4_DU
,
DIV4_P
,
DIV4_NR
};
#define DIV4(_
str, _
bit, _mask, _flags) \
SH_CLK_DIV4(
_str,
&pll_clk, FRQMR1, _bit, _mask, _flags)
#define DIV4(_bit, _mask, _flags) \
SH_CLK_DIV4(&pll_clk, FRQMR1, _bit, _mask, _flags)
struct
clk
div4_clks
[
DIV4_NR
]
=
{
[
DIV4_P
]
=
DIV4
(
"peripheral_clk"
,
0
,
0x0b40
,
0
),
[
DIV4_DU
]
=
DIV4
(
"du_clk"
,
4
,
0x0010
,
0
),
[
DIV4_DDR
]
=
DIV4
(
"ddr_clk"
,
12
,
0x0002
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
"bus_clk"
,
16
,
0x0360
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
"shyway_clk"
,
20
,
0x0002
,
CLK_ENABLE_ON_INIT
),
[
DIV4_I
]
=
DIV4
(
"cpu_clk"
,
28
,
0x0006
,
CLK_ENABLE_ON_INIT
),
[
DIV4_P
]
=
DIV4
(
0
,
0x0b40
,
0
),
[
DIV4_DU
]
=
DIV4
(
4
,
0x0010
,
0
),
[
DIV4_DDR
]
=
DIV4
(
12
,
0x0002
,
CLK_ENABLE_ON_INIT
),
[
DIV4_B
]
=
DIV4
(
16
,
0x0360
,
CLK_ENABLE_ON_INIT
),
[
DIV4_SH
]
=
DIV4
(
20
,
0x0002
,
CLK_ENABLE_ON_INIT
),
[
DIV4_I
]
=
DIV4
(
28
,
0x0006
,
CLK_ENABLE_ON_INIT
),
};
#define MSTPCR0 0xffc40030
#define MSTPCR1 0xffc40034
static
struct
clk
mstp_clks
[]
=
{
enum
{
MSTP029
,
MSTP028
,
MSTP027
,
MSTP026
,
MSTP025
,
MSTP024
,
MSTP023
,
MSTP022
,
MSTP021
,
MSTP020
,
MSTP017
,
MSTP016
,
MSTP015
,
MSTP014
,
MSTP011
,
MSTP010
,
MSTP009
,
MSTP008
,
MSTP005
,
MSTP004
,
MSTP002
,
MSTP112
,
MSTP110
,
MSTP109
,
MSTP108
,
MSTP105
,
MSTP104
,
MSTP103
,
MSTP102
,
MSTP_NR
};
static
struct
clk
mstp_clks
[
MSTP_NR
]
=
{
/* MSTPCR0 */
SH_CLK_MSTP32
(
"sci_fck"
,
5
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
29
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
4
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
28
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
3
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
27
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
2
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
26
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
25
,
0
),
SH_CLK_MSTP32
(
"sci_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
24
,
0
),
SH_CLK_MSTP32
(
"ssi_fck"
,
3
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
23
,
0
),
SH_CLK_MSTP32
(
"ssi_fck"
,
2
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
22
,
0
),
SH_CLK_MSTP32
(
"ssi_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
SH_CLK_MSTP32
(
"ssi_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
SH_CLK_MSTP32
(
"hac_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
SH_CLK_MSTP32
(
"hac_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
16
,
0
),
SH_CLK_MSTP32
(
"i2c_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
15
,
0
),
SH_CLK_MSTP32
(
"i2c_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
14
,
0
),
SH_CLK_MSTP32
(
"tmu9_11_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
11
,
0
),
SH_CLK_MSTP32
(
"tmu678_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
10
,
0
),
SH_CLK_MSTP32
(
"tmu345_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
9
,
0
),
SH_CLK_MSTP32
(
"tmu012_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
8
,
0
),
SH_CLK_MSTP32
(
"sdif_fck"
,
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
5
,
0
),
SH_CLK_MSTP32
(
"sdif_fck"
,
0
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
4
,
0
),
SH_CLK_MSTP32
(
"hspi_fck"
,
-
1
,
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
[
MSTP029
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
29
,
0
),
[
MSTP028
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
28
,
0
),
[
MSTP027
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
27
,
0
),
[
MSTP026
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
26
,
0
),
[
MSTP025
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
25
,
0
),
[
MSTP024
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
24
,
0
),
[
MSTP023
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
23
,
0
),
[
MSTP022
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
22
,
0
),
[
MSTP021
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
21
,
0
),
[
MSTP020
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
20
,
0
),
[
MSTP017
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
17
,
0
),
[
MSTP016
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
16
,
0
),
[
MSTP015
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
15
,
0
),
[
MSTP014
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
14
,
0
),
[
MSTP011
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
11
,
0
),
[
MSTP010
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
10
,
0
),
[
MSTP009
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
9
,
0
),
[
MSTP008
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
8
,
0
),
[
MSTP005
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
5
,
0
),
[
MSTP004
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
4
,
0
),
[
MSTP002
]
=
SH_CLK_MSTP32
(
&
div4_clks
[
DIV4_P
],
MSTPCR0
,
2
,
0
),
/* MSTPCR1 */
SH_CLK_MSTP32
(
"usb_fck"
,
-
1
,
NULL
,
MSTPCR1
,
12
,
0
),
SH_CLK_MSTP32
(
"pcie_fck"
,
2
,
NULL
,
MSTPCR1
,
10
,
0
),
SH_CLK_MSTP32
(
"pcie_fck"
,
1
,
NULL
,
MSTPCR1
,
9
,
0
),
SH_CLK_MSTP32
(
"pcie_fck"
,
0
,
NULL
,
MSTPCR1
,
8
,
0
),
SH_CLK_MSTP32
(
"dmac_11_6_fck"
,
-
1
,
NULL
,
MSTPCR1
,
5
,
0
),
SH_CLK_MSTP32
(
"dmac_5_0_fck"
,
-
1
,
NULL
,
MSTPCR1
,
4
,
0
),
SH_CLK_MSTP32
(
"du_fck"
,
-
1
,
NULL
,
MSTPCR1
,
3
,
0
),
SH_CLK_MSTP32
(
"ether_fck"
,
-
1
,
NULL
,
MSTPCR1
,
2
,
0
),
[
MSTP112
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
12
,
0
),
[
MSTP110
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
10
,
0
),
[
MSTP109
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
9
,
0
),
[
MSTP108
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
8
,
0
),
[
MSTP105
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
5
,
0
),
[
MSTP104
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
4
,
0
),
[
MSTP103
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
3
,
0
),
[
MSTP102
]
=
SH_CLK_MSTP32
(
NULL
,
MSTPCR1
,
2
,
0
),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"extal"
,
&
extal_clk
),
CLKDEV_CON_ID
(
"pll_clk"
,
&
pll_clk
),
/* DIV4 clocks */
CLKDEV_CON_ID
(
"peripheral_clk"
,
&
div4_clks
[
DIV4_P
]),
CLKDEV_CON_ID
(
"du_clk"
,
&
div4_clks
[
DIV4_DU
]),
CLKDEV_CON_ID
(
"ddr_clk"
,
&
div4_clks
[
DIV4_DDR
]),
CLKDEV_CON_ID
(
"bus_clk"
,
&
div4_clks
[
DIV4_B
]),
CLKDEV_CON_ID
(
"shyway_clk"
,
&
div4_clks
[
DIV4_SH
]),
CLKDEV_CON_ID
(
"cpu_clk"
,
&
div4_clks
[
DIV4_I
]),
/* MSTP32 clocks */
{
/* SCIF5 */
.
dev_id
=
"sh-sci.5"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP029
],
},
{
/* SCIF4 */
.
dev_id
=
"sh-sci.4"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP028
],
},
{
/* SCIF3 */
.
dev_id
=
"sh-sci.3"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP027
],
},
{
/* SCIF2 */
.
dev_id
=
"sh-sci.2"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP026
],
},
{
/* SCIF1 */
.
dev_id
=
"sh-sci.1"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP025
],
},
{
/* SCIF0 */
.
dev_id
=
"sh-sci.0"
,
.
con_id
=
"sci_fck"
,
.
clk
=
&
mstp_clks
[
MSTP024
],
},
CLKDEV_CON_ID
(
"ssi3_fck"
,
&
mstp_clks
[
MSTP023
]),
CLKDEV_CON_ID
(
"ssi2_fck"
,
&
mstp_clks
[
MSTP022
]),
CLKDEV_CON_ID
(
"ssi1_fck"
,
&
mstp_clks
[
MSTP021
]),
CLKDEV_CON_ID
(
"ssi0_fck"
,
&
mstp_clks
[
MSTP020
]),
CLKDEV_CON_ID
(
"hac1_fck"
,
&
mstp_clks
[
MSTP017
]),
CLKDEV_CON_ID
(
"hac0_fck"
,
&
mstp_clks
[
MSTP016
]),
CLKDEV_CON_ID
(
"i2c1_fck"
,
&
mstp_clks
[
MSTP015
]),
CLKDEV_CON_ID
(
"i2c0_fck"
,
&
mstp_clks
[
MSTP014
]),
{
/* TMU0 */
.
dev_id
=
"sh_tmu.0"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
17
],
/* tmu012_fck */
.
clk
=
&
mstp_clks
[
MSTP008
],
},
{
/* TMU1 */
.
dev_id
=
"sh_tmu.1"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
17
],
.
clk
=
&
mstp_clks
[
MSTP008
],
},
{
/* TMU2 */
.
dev_id
=
"sh_tmu.2"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
17
],
.
clk
=
&
mstp_clks
[
MSTP008
],
},
{
/* TMU3 */
.
dev_id
=
"sh_tmu.3"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
16
],
/* tmu345_fck */
.
clk
=
&
mstp_clks
[
MSTP009
],
},
{
/* TMU4 */
.
dev_id
=
"sh_tmu.4"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
16
],
.
clk
=
&
mstp_clks
[
MSTP009
],
},
{
/* TMU5 */
.
dev_id
=
"sh_tmu.5"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
16
],
.
clk
=
&
mstp_clks
[
MSTP009
],
},
{
/* TMU6 */
.
dev_id
=
"sh_tmu.6"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
15
],
/* tmu678_fck */
.
clk
=
&
mstp_clks
[
MSTP010
],
},
{
/* TMU7 */
.
dev_id
=
"sh_tmu.7"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
15
],
.
clk
=
&
mstp_clks
[
MSTP010
],
},
{
/* TMU8 */
.
dev_id
=
"sh_tmu.8"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
15
],
.
clk
=
&
mstp_clks
[
MSTP010
],
},
{
/* TMU9 */
.
dev_id
=
"sh_tmu.9"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
14
],
/* tmu9_11_fck */
.
clk
=
&
mstp_clks
[
MSTP011
],
},
{
/* TMU10 */
.
dev_id
=
"sh_tmu.10"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
14
],
.
clk
=
&
mstp_clks
[
MSTP011
],
},
{
/* TMU11 */
.
dev_id
=
"sh_tmu.11"
,
.
con_id
=
"tmu_fck"
,
.
clk
=
&
mstp_clks
[
14
],
}
.
clk
=
&
mstp_clks
[
MSTP011
],
},
CLKDEV_CON_ID
(
"sdif1_fck"
,
&
mstp_clks
[
MSTP005
]),
CLKDEV_CON_ID
(
"sdif0_fck"
,
&
mstp_clks
[
MSTP004
]),
CLKDEV_CON_ID
(
"hspi_fck"
,
&
mstp_clks
[
MSTP002
]),
CLKDEV_CON_ID
(
"usb_fck"
,
&
mstp_clks
[
MSTP112
]),
CLKDEV_CON_ID
(
"pcie2_fck"
,
&
mstp_clks
[
MSTP110
]),
CLKDEV_CON_ID
(
"pcie1_fck"
,
&
mstp_clks
[
MSTP109
]),
CLKDEV_CON_ID
(
"pcie0_fck"
,
&
mstp_clks
[
MSTP108
]),
CLKDEV_CON_ID
(
"dmac_11_6_fck"
,
&
mstp_clks
[
MSTP105
]),
CLKDEV_CON_ID
(
"dmac_5_0_fck"
,
&
mstp_clks
[
MSTP104
]),
CLKDEV_CON_ID
(
"du_fck"
,
&
mstp_clks
[
MSTP103
]),
CLKDEV_CON_ID
(
"ether_fck"
,
&
mstp_clks
[
MSTP102
]),
};
int
__init
arch_clk_init
(
void
)
...
...
@@ -199,7 +268,7 @@ int __init arch_clk_init(void)
ret
=
sh_clk_div4_register
(
div4_clks
,
ARRAY_SIZE
(
div4_clks
),
&
div4_table
);
if
(
!
ret
)
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
ARRAY_SIZE
(
mstp_clks
)
);
ret
=
sh_clk_mstp32_register
(
mstp_clks
,
MSTP_NR
);
return
ret
;
}
arch/sh/kernel/cpu/sh4a/clock-shx3.c
浏览文件 @
c5eb5b37
...
...
@@ -13,9 +13,10 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>
static
int
ifc_divisors
[]
=
{
1
,
2
,
4
,
6
};
static
int
bfc_divisors
[]
=
{
1
,
1
,
1
,
1
,
1
,
12
,
16
,
18
,
24
,
32
,
36
,
48
};
...
...
@@ -94,7 +95,6 @@ static struct clk_ops shx3_shyway_clk_ops = {
};
static
struct
clk
shx3_shyway_clk
=
{
.
name
=
"shyway_clk"
,
.
flags
=
CLK_ENABLE_ON_INIT
,
.
ops
=
&
shx3_shyway_clk_ops
,
};
...
...
@@ -107,6 +107,13 @@ static struct clk *shx3_onchip_clocks[] = {
&
shx3_shyway_clk
,
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static
struct
clk_lookup
lookups
[]
=
{
/* main clocks */
CLKDEV_CON_ID
(
"shyway_clk"
,
&
shx3_shyway_clk
),
};
int
__init
arch_clk_init
(
void
)
{
struct
clk
*
clk
;
...
...
@@ -124,5 +131,7 @@ int __init arch_clk_init(void)
clk_put
(
clk
);
clkdev_add_table
(
lookups
,
ARRAY_SIZE
(
lookups
));
return
ret
;
}
drivers/sh/Makefile
浏览文件 @
c5eb5b37
...
...
@@ -4,4 +4,6 @@
obj-$(CONFIG_SUPERHYWAY)
+=
superhyway/
obj-$(CONFIG_MAPLE)
+=
maple/
obj-$(CONFIG_GENERIC_GPIO)
+=
pfc.o
obj-$(CONFIG_SUPERH)
+=
clk.o
obj-$(CONFIG_SH_CLK_CPG)
+=
clk-cpg.o
obj-y
+=
intc.o
drivers/sh/clk-cpg.c
0 → 100644
浏览文件 @
c5eb5b37
#include <linux/clk.h>
#include <linux/compiler.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/sh_clk.h>
static
int
sh_clk_mstp32_enable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
&
~
(
1
<<
clk
->
enable_bit
),
clk
->
enable_reg
);
return
0
;
}
static
void
sh_clk_mstp32_disable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
|
(
1
<<
clk
->
enable_bit
),
clk
->
enable_reg
);
}
static
struct
clk_ops
sh_clk_mstp32_clk_ops
=
{
.
enable
=
sh_clk_mstp32_enable
,
.
disable
=
sh_clk_mstp32_disable
,
.
recalc
=
followparent_recalc
,
};
int
__init
sh_clk_mstp32_register
(
struct
clk
*
clks
,
int
nr
)
{
struct
clk
*
clkp
;
int
ret
=
0
;
int
k
;
for
(
k
=
0
;
!
ret
&&
(
k
<
nr
);
k
++
)
{
clkp
=
clks
+
k
;
clkp
->
ops
=
&
sh_clk_mstp32_clk_ops
;
ret
|=
clk_register
(
clkp
);
}
return
ret
;
}
static
long
sh_clk_div_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
clk_rate_table_round
(
clk
,
clk
->
freq_table
,
rate
);
}
static
int
sh_clk_div6_divisors
[
64
]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
};
static
struct
clk_div_mult_table
sh_clk_div6_table
=
{
.
divisors
=
sh_clk_div6_divisors
,
.
nr_divisors
=
ARRAY_SIZE
(
sh_clk_div6_divisors
),
};
static
unsigned
long
sh_clk_div6_recalc
(
struct
clk
*
clk
)
{
struct
clk_div_mult_table
*
table
=
&
sh_clk_div6_table
;
unsigned
int
idx
;
clk_rate_table_build
(
clk
,
clk
->
freq_table
,
table
->
nr_divisors
,
table
,
NULL
);
idx
=
__raw_readl
(
clk
->
enable_reg
)
&
0x003f
;
return
clk
->
freq_table
[
idx
].
frequency
;
}
static
int
sh_clk_div6_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
)
{
unsigned
long
value
;
int
idx
;
idx
=
clk_rate_table_find
(
clk
,
clk
->
freq_table
,
rate
);
if
(
idx
<
0
)
return
idx
;
value
=
__raw_readl
(
clk
->
enable_reg
);
value
&=
~
0x3f
;
value
|=
idx
;
__raw_writel
(
value
,
clk
->
enable_reg
);
return
0
;
}
static
int
sh_clk_div6_enable
(
struct
clk
*
clk
)
{
unsigned
long
value
;
int
ret
;
ret
=
sh_clk_div6_set_rate
(
clk
,
clk
->
rate
,
0
);
if
(
ret
==
0
)
{
value
=
__raw_readl
(
clk
->
enable_reg
);
value
&=
~
0x100
;
/* clear stop bit to enable clock */
__raw_writel
(
value
,
clk
->
enable_reg
);
}
return
ret
;
}
static
void
sh_clk_div6_disable
(
struct
clk
*
clk
)
{
unsigned
long
value
;
value
=
__raw_readl
(
clk
->
enable_reg
);
value
|=
0x100
;
/* stop clock */
value
|=
0x3f
;
/* VDIV bits must be non-zero, overwrite divider */
__raw_writel
(
value
,
clk
->
enable_reg
);
}
static
struct
clk_ops
sh_clk_div6_clk_ops
=
{
.
recalc
=
sh_clk_div6_recalc
,
.
round_rate
=
sh_clk_div_round_rate
,
.
set_rate
=
sh_clk_div6_set_rate
,
.
enable
=
sh_clk_div6_enable
,
.
disable
=
sh_clk_div6_disable
,
};
int
__init
sh_clk_div6_register
(
struct
clk
*
clks
,
int
nr
)
{
struct
clk
*
clkp
;
void
*
freq_table
;
int
nr_divs
=
sh_clk_div6_table
.
nr_divisors
;
int
freq_table_size
=
sizeof
(
struct
cpufreq_frequency_table
);
int
ret
=
0
;
int
k
;
freq_table_size
*=
(
nr_divs
+
1
);
freq_table
=
kzalloc
(
freq_table_size
*
nr
,
GFP_KERNEL
);
if
(
!
freq_table
)
{
pr_err
(
"sh_clk_div6_register: unable to alloc memory
\n
"
);
return
-
ENOMEM
;
}
for
(
k
=
0
;
!
ret
&&
(
k
<
nr
);
k
++
)
{
clkp
=
clks
+
k
;
clkp
->
ops
=
&
sh_clk_div6_clk_ops
;
clkp
->
id
=
-
1
;
clkp
->
freq_table
=
freq_table
+
(
k
*
freq_table_size
);
clkp
->
freq_table
[
nr_divs
].
frequency
=
CPUFREQ_TABLE_END
;
ret
=
clk_register
(
clkp
);
}
return
ret
;
}
static
unsigned
long
sh_clk_div4_recalc
(
struct
clk
*
clk
)
{
struct
clk_div4_table
*
d4t
=
clk
->
priv
;
struct
clk_div_mult_table
*
table
=
d4t
->
div_mult_table
;
unsigned
int
idx
;
clk_rate_table_build
(
clk
,
clk
->
freq_table
,
table
->
nr_divisors
,
table
,
&
clk
->
arch_flags
);
idx
=
(
__raw_readl
(
clk
->
enable_reg
)
>>
clk
->
enable_bit
)
&
0x000f
;
return
clk
->
freq_table
[
idx
].
frequency
;
}
static
int
sh_clk_div4_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
struct
clk_div4_table
*
d4t
=
clk
->
priv
;
struct
clk_div_mult_table
*
table
=
d4t
->
div_mult_table
;
u32
value
;
int
ret
;
/* we really need a better way to determine parent index, but for
* now assume internal parent comes with CLK_ENABLE_ON_INIT set,
* no CLK_ENABLE_ON_INIT means external clock...
*/
if
(
parent
->
flags
&
CLK_ENABLE_ON_INIT
)
value
=
__raw_readl
(
clk
->
enable_reg
)
&
~
(
1
<<
7
);
else
value
=
__raw_readl
(
clk
->
enable_reg
)
|
(
1
<<
7
);
ret
=
clk_reparent
(
clk
,
parent
);
if
(
ret
<
0
)
return
ret
;
__raw_writel
(
value
,
clk
->
enable_reg
);
/* Rebiuld the frequency table */
clk_rate_table_build
(
clk
,
clk
->
freq_table
,
table
->
nr_divisors
,
table
,
&
clk
->
arch_flags
);
return
0
;
}
static
int
sh_clk_div4_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
)
{
struct
clk_div4_table
*
d4t
=
clk
->
priv
;
unsigned
long
value
;
int
idx
=
clk_rate_table_find
(
clk
,
clk
->
freq_table
,
rate
);
if
(
idx
<
0
)
return
idx
;
value
=
__raw_readl
(
clk
->
enable_reg
);
value
&=
~
(
0xf
<<
clk
->
enable_bit
);
value
|=
(
idx
<<
clk
->
enable_bit
);
__raw_writel
(
value
,
clk
->
enable_reg
);
if
(
d4t
->
kick
)
d4t
->
kick
(
clk
);
return
0
;
}
static
int
sh_clk_div4_enable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
&
~
(
1
<<
8
),
clk
->
enable_reg
);
return
0
;
}
static
void
sh_clk_div4_disable
(
struct
clk
*
clk
)
{
__raw_writel
(
__raw_readl
(
clk
->
enable_reg
)
|
(
1
<<
8
),
clk
->
enable_reg
);
}
static
struct
clk_ops
sh_clk_div4_clk_ops
=
{
.
recalc
=
sh_clk_div4_recalc
,
.
set_rate
=
sh_clk_div4_set_rate
,
.
round_rate
=
sh_clk_div_round_rate
,
};
static
struct
clk_ops
sh_clk_div4_enable_clk_ops
=
{
.
recalc
=
sh_clk_div4_recalc
,
.
set_rate
=
sh_clk_div4_set_rate
,
.
round_rate
=
sh_clk_div_round_rate
,
.
enable
=
sh_clk_div4_enable
,
.
disable
=
sh_clk_div4_disable
,
};
static
struct
clk_ops
sh_clk_div4_reparent_clk_ops
=
{
.
recalc
=
sh_clk_div4_recalc
,
.
set_rate
=
sh_clk_div4_set_rate
,
.
round_rate
=
sh_clk_div_round_rate
,
.
enable
=
sh_clk_div4_enable
,
.
disable
=
sh_clk_div4_disable
,
.
set_parent
=
sh_clk_div4_set_parent
,
};
static
int
__init
sh_clk_div4_register_ops
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
,
struct
clk_ops
*
ops
)
{
struct
clk
*
clkp
;
void
*
freq_table
;
int
nr_divs
=
table
->
div_mult_table
->
nr_divisors
;
int
freq_table_size
=
sizeof
(
struct
cpufreq_frequency_table
);
int
ret
=
0
;
int
k
;
freq_table_size
*=
(
nr_divs
+
1
);
freq_table
=
kzalloc
(
freq_table_size
*
nr
,
GFP_KERNEL
);
if
(
!
freq_table
)
{
pr_err
(
"sh_clk_div4_register: unable to alloc memory
\n
"
);
return
-
ENOMEM
;
}
for
(
k
=
0
;
!
ret
&&
(
k
<
nr
);
k
++
)
{
clkp
=
clks
+
k
;
clkp
->
ops
=
ops
;
clkp
->
id
=
-
1
;
clkp
->
priv
=
table
;
clkp
->
freq_table
=
freq_table
+
(
k
*
freq_table_size
);
clkp
->
freq_table
[
nr_divs
].
frequency
=
CPUFREQ_TABLE_END
;
ret
=
clk_register
(
clkp
);
}
return
ret
;
}
int
__init
sh_clk_div4_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
)
{
return
sh_clk_div4_register_ops
(
clks
,
nr
,
table
,
&
sh_clk_div4_clk_ops
);
}
int
__init
sh_clk_div4_enable_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
)
{
return
sh_clk_div4_register_ops
(
clks
,
nr
,
table
,
&
sh_clk_div4_enable_clk_ops
);
}
int
__init
sh_clk_div4_reparent_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
)
{
return
sh_clk_div4_register_ops
(
clks
,
nr
,
table
,
&
sh_clk_div4_reparent_clk_ops
);
}
drivers/sh/clk.c
0 → 100644
浏览文件 @
c5eb5b37
/*
* drivers/sh/clk.c - SuperH clock framework
*
* Copyright (C) 2005 - 2009 Paul Mundt
*
* This clock framework is derived from the OMAP version by:
*
* Copyright (C) 2004 - 2008 Nokia Corporation
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
*
* Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/kobject.h>
#include <linux/sysdev.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/sh_clk.h>
static
LIST_HEAD
(
clock_list
);
static
DEFINE_SPINLOCK
(
clock_lock
);
static
DEFINE_MUTEX
(
clock_list_sem
);
void
clk_rate_table_build
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
int
nr_freqs
,
struct
clk_div_mult_table
*
src_table
,
unsigned
long
*
bitmap
)
{
unsigned
long
mult
,
div
;
unsigned
long
freq
;
int
i
;
for
(
i
=
0
;
i
<
nr_freqs
;
i
++
)
{
div
=
1
;
mult
=
1
;
if
(
src_table
->
divisors
&&
i
<
src_table
->
nr_divisors
)
div
=
src_table
->
divisors
[
i
];
if
(
src_table
->
multipliers
&&
i
<
src_table
->
nr_multipliers
)
mult
=
src_table
->
multipliers
[
i
];
if
(
!
div
||
!
mult
||
(
bitmap
&&
!
test_bit
(
i
,
bitmap
)))
freq
=
CPUFREQ_ENTRY_INVALID
;
else
freq
=
clk
->
parent
->
rate
*
mult
/
div
;
freq_table
[
i
].
index
=
i
;
freq_table
[
i
].
frequency
=
freq
;
}
/* Termination entry */
freq_table
[
i
].
index
=
i
;
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
}
long
clk_rate_table_round
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
)
{
unsigned
long
rate_error
,
rate_error_prev
=
~
0UL
;
unsigned
long
rate_best_fit
=
rate
;
unsigned
long
highest
,
lowest
;
int
i
;
highest
=
lowest
=
0
;
for
(
i
=
0
;
freq_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
unsigned
long
freq
=
freq_table
[
i
].
frequency
;
if
(
freq
==
CPUFREQ_ENTRY_INVALID
)
continue
;
if
(
freq
>
highest
)
highest
=
freq
;
if
(
freq
<
lowest
)
lowest
=
freq
;
rate_error
=
abs
(
freq
-
rate
);
if
(
rate_error
<
rate_error_prev
)
{
rate_best_fit
=
freq
;
rate_error_prev
=
rate_error
;
}
if
(
rate_error
==
0
)
break
;
}
if
(
rate
>=
highest
)
rate_best_fit
=
highest
;
if
(
rate
<=
lowest
)
rate_best_fit
=
lowest
;
return
rate_best_fit
;
}
int
clk_rate_table_find
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
)
{
int
i
;
for
(
i
=
0
;
freq_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
;
i
++
)
{
unsigned
long
freq
=
freq_table
[
i
].
frequency
;
if
(
freq
==
CPUFREQ_ENTRY_INVALID
)
continue
;
if
(
freq
==
rate
)
return
i
;
}
return
-
ENOENT
;
}
/* Used for clocks that always have same value as the parent clock */
unsigned
long
followparent_recalc
(
struct
clk
*
clk
)
{
return
clk
->
parent
?
clk
->
parent
->
rate
:
0
;
}
int
clk_reparent
(
struct
clk
*
child
,
struct
clk
*
parent
)
{
list_del_init
(
&
child
->
sibling
);
if
(
parent
)
list_add
(
&
child
->
sibling
,
&
parent
->
children
);
child
->
parent
=
parent
;
/* now do the debugfs renaming to reattach the child
to the proper parent */
return
0
;
}
/* Propagate rate to children */
void
propagate_rate
(
struct
clk
*
tclk
)
{
struct
clk
*
clkp
;
list_for_each_entry
(
clkp
,
&
tclk
->
children
,
sibling
)
{
if
(
clkp
->
ops
&&
clkp
->
ops
->
recalc
)
clkp
->
rate
=
clkp
->
ops
->
recalc
(
clkp
);
propagate_rate
(
clkp
);
}
}
static
void
__clk_disable
(
struct
clk
*
clk
)
{
if
(
WARN
(
!
clk
->
usecount
,
"Trying to disable clock %s with 0 usecount
\n
"
,
clk
->
name
))
return
;
if
(
!
(
--
clk
->
usecount
))
{
if
(
likely
(
clk
->
ops
&&
clk
->
ops
->
disable
))
clk
->
ops
->
disable
(
clk
);
if
(
likely
(
clk
->
parent
))
__clk_disable
(
clk
->
parent
);
}
}
void
clk_disable
(
struct
clk
*
clk
)
{
unsigned
long
flags
;
if
(
!
clk
)
return
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
__clk_disable
(
clk
);
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
clk_disable
);
static
int
__clk_enable
(
struct
clk
*
clk
)
{
int
ret
=
0
;
if
(
clk
->
usecount
++
==
0
)
{
if
(
clk
->
parent
)
{
ret
=
__clk_enable
(
clk
->
parent
);
if
(
unlikely
(
ret
))
goto
err
;
}
if
(
clk
->
ops
&&
clk
->
ops
->
enable
)
{
ret
=
clk
->
ops
->
enable
(
clk
);
if
(
ret
)
{
if
(
clk
->
parent
)
__clk_disable
(
clk
->
parent
);
goto
err
;
}
}
}
return
ret
;
err:
clk
->
usecount
--
;
return
ret
;
}
int
clk_enable
(
struct
clk
*
clk
)
{
unsigned
long
flags
;
int
ret
;
if
(
!
clk
)
return
-
EINVAL
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
ret
=
__clk_enable
(
clk
);
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
clk_enable
);
static
LIST_HEAD
(
root_clks
);
/**
* recalculate_root_clocks - recalculate and propagate all root clocks
*
* Recalculates all root clocks (clocks with no parent), which if the
* clock's .recalc is set correctly, should also propagate their rates.
* Called at init.
*/
void
recalculate_root_clocks
(
void
)
{
struct
clk
*
clkp
;
list_for_each_entry
(
clkp
,
&
root_clks
,
sibling
)
{
if
(
clkp
->
ops
&&
clkp
->
ops
->
recalc
)
clkp
->
rate
=
clkp
->
ops
->
recalc
(
clkp
);
propagate_rate
(
clkp
);
}
}
int
clk_register
(
struct
clk
*
clk
)
{
if
(
clk
==
NULL
||
IS_ERR
(
clk
))
return
-
EINVAL
;
/*
* trap out already registered clocks
*/
if
(
clk
->
node
.
next
||
clk
->
node
.
prev
)
return
0
;
mutex_lock
(
&
clock_list_sem
);
INIT_LIST_HEAD
(
&
clk
->
children
);
clk
->
usecount
=
0
;
if
(
clk
->
parent
)
list_add
(
&
clk
->
sibling
,
&
clk
->
parent
->
children
);
else
list_add
(
&
clk
->
sibling
,
&
root_clks
);
list_add
(
&
clk
->
node
,
&
clock_list
);
if
(
clk
->
ops
&&
clk
->
ops
->
init
)
clk
->
ops
->
init
(
clk
);
mutex_unlock
(
&
clock_list_sem
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
clk_register
);
void
clk_unregister
(
struct
clk
*
clk
)
{
mutex_lock
(
&
clock_list_sem
);
list_del
(
&
clk
->
sibling
);
list_del
(
&
clk
->
node
);
mutex_unlock
(
&
clock_list_sem
);
}
EXPORT_SYMBOL_GPL
(
clk_unregister
);
void
clk_enable_init_clocks
(
void
)
{
struct
clk
*
clkp
;
list_for_each_entry
(
clkp
,
&
clock_list
,
node
)
if
(
clkp
->
flags
&
CLK_ENABLE_ON_INIT
)
clk_enable
(
clkp
);
}
unsigned
long
clk_get_rate
(
struct
clk
*
clk
)
{
return
clk
->
rate
;
}
EXPORT_SYMBOL_GPL
(
clk_get_rate
);
int
clk_set_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
return
clk_set_rate_ex
(
clk
,
rate
,
0
);
}
EXPORT_SYMBOL_GPL
(
clk_set_rate
);
int
clk_set_rate_ex
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
)
{
int
ret
=
-
EOPNOTSUPP
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
if
(
likely
(
clk
->
ops
&&
clk
->
ops
->
set_rate
))
{
ret
=
clk
->
ops
->
set_rate
(
clk
,
rate
,
algo_id
);
if
(
ret
!=
0
)
goto
out_unlock
;
}
else
{
clk
->
rate
=
rate
;
ret
=
0
;
}
if
(
clk
->
ops
&&
clk
->
ops
->
recalc
)
clk
->
rate
=
clk
->
ops
->
recalc
(
clk
);
propagate_rate
(
clk
);
out_unlock:
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
clk_set_rate_ex
);
int
clk_set_parent
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
flags
;
int
ret
=
-
EINVAL
;
if
(
!
parent
||
!
clk
)
return
ret
;
if
(
clk
->
parent
==
parent
)
return
0
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
if
(
clk
->
usecount
==
0
)
{
if
(
clk
->
ops
->
set_parent
)
ret
=
clk
->
ops
->
set_parent
(
clk
,
parent
);
else
ret
=
clk_reparent
(
clk
,
parent
);
if
(
ret
==
0
)
{
pr_debug
(
"clock: set parent of %s to %s (new rate %ld)
\n
"
,
clk
->
name
,
clk
->
parent
->
name
,
clk
->
rate
);
if
(
clk
->
ops
->
recalc
)
clk
->
rate
=
clk
->
ops
->
recalc
(
clk
);
propagate_rate
(
clk
);
}
}
else
ret
=
-
EBUSY
;
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
clk_set_parent
);
struct
clk
*
clk_get_parent
(
struct
clk
*
clk
)
{
return
clk
->
parent
;
}
EXPORT_SYMBOL_GPL
(
clk_get_parent
);
long
clk_round_rate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
if
(
likely
(
clk
->
ops
&&
clk
->
ops
->
round_rate
))
{
unsigned
long
flags
,
rounded
;
spin_lock_irqsave
(
&
clock_lock
,
flags
);
rounded
=
clk
->
ops
->
round_rate
(
clk
,
rate
);
spin_unlock_irqrestore
(
&
clock_lock
,
flags
);
return
rounded
;
}
return
clk_get_rate
(
clk
);
}
EXPORT_SYMBOL_GPL
(
clk_round_rate
);
#ifdef CONFIG_PM
static
int
clks_sysdev_suspend
(
struct
sys_device
*
dev
,
pm_message_t
state
)
{
static
pm_message_t
prev_state
;
struct
clk
*
clkp
;
switch
(
state
.
event
)
{
case
PM_EVENT_ON
:
/* Resumeing from hibernation */
if
(
prev_state
.
event
!=
PM_EVENT_FREEZE
)
break
;
list_for_each_entry
(
clkp
,
&
clock_list
,
node
)
{
if
(
likely
(
clkp
->
ops
))
{
unsigned
long
rate
=
clkp
->
rate
;
if
(
likely
(
clkp
->
ops
->
set_parent
))
clkp
->
ops
->
set_parent
(
clkp
,
clkp
->
parent
);
if
(
likely
(
clkp
->
ops
->
set_rate
))
clkp
->
ops
->
set_rate
(
clkp
,
rate
,
NO_CHANGE
);
else
if
(
likely
(
clkp
->
ops
->
recalc
))
clkp
->
rate
=
clkp
->
ops
->
recalc
(
clkp
);
}
}
break
;
case
PM_EVENT_FREEZE
:
break
;
case
PM_EVENT_SUSPEND
:
break
;
}
prev_state
=
state
;
return
0
;
}
static
int
clks_sysdev_resume
(
struct
sys_device
*
dev
)
{
return
clks_sysdev_suspend
(
dev
,
PMSG_ON
);
}
static
struct
sysdev_class
clks_sysdev_class
=
{
.
name
=
"clks"
,
};
static
struct
sysdev_driver
clks_sysdev_driver
=
{
.
suspend
=
clks_sysdev_suspend
,
.
resume
=
clks_sysdev_resume
,
};
static
struct
sys_device
clks_sysdev_dev
=
{
.
cls
=
&
clks_sysdev_class
,
};
static
int
__init
clk_sysdev_init
(
void
)
{
sysdev_class_register
(
&
clks_sysdev_class
);
sysdev_driver_register
(
&
clks_sysdev_class
,
&
clks_sysdev_driver
);
sysdev_register
(
&
clks_sysdev_dev
);
return
0
;
}
subsys_initcall
(
clk_sysdev_init
);
#endif
/*
* debugfs support to trace clock tree hierarchy and attributes
*/
static
struct
dentry
*
clk_debugfs_root
;
static
int
clk_debugfs_register_one
(
struct
clk
*
c
)
{
int
err
;
struct
dentry
*
d
,
*
child
,
*
child_tmp
;
struct
clk
*
pa
=
c
->
parent
;
char
s
[
255
];
char
*
p
=
s
;
p
+=
sprintf
(
p
,
"%s"
,
c
->
name
);
if
(
c
->
id
>=
0
)
sprintf
(
p
,
":%d"
,
c
->
id
);
d
=
debugfs_create_dir
(
s
,
pa
?
pa
->
dentry
:
clk_debugfs_root
);
if
(
!
d
)
return
-
ENOMEM
;
c
->
dentry
=
d
;
d
=
debugfs_create_u8
(
"usecount"
,
S_IRUGO
,
c
->
dentry
,
(
u8
*
)
&
c
->
usecount
);
if
(
!
d
)
{
err
=
-
ENOMEM
;
goto
err_out
;
}
d
=
debugfs_create_u32
(
"rate"
,
S_IRUGO
,
c
->
dentry
,
(
u32
*
)
&
c
->
rate
);
if
(
!
d
)
{
err
=
-
ENOMEM
;
goto
err_out
;
}
d
=
debugfs_create_x32
(
"flags"
,
S_IRUGO
,
c
->
dentry
,
(
u32
*
)
&
c
->
flags
);
if
(
!
d
)
{
err
=
-
ENOMEM
;
goto
err_out
;
}
return
0
;
err_out:
d
=
c
->
dentry
;
list_for_each_entry_safe
(
child
,
child_tmp
,
&
d
->
d_subdirs
,
d_u
.
d_child
)
debugfs_remove
(
child
);
debugfs_remove
(
c
->
dentry
);
return
err
;
}
static
int
clk_debugfs_register
(
struct
clk
*
c
)
{
int
err
;
struct
clk
*
pa
=
c
->
parent
;
if
(
pa
&&
!
pa
->
dentry
)
{
err
=
clk_debugfs_register
(
pa
);
if
(
err
)
return
err
;
}
if
(
!
c
->
dentry
&&
c
->
name
)
{
err
=
clk_debugfs_register_one
(
c
);
if
(
err
)
return
err
;
}
return
0
;
}
static
int
__init
clk_debugfs_init
(
void
)
{
struct
clk
*
c
;
struct
dentry
*
d
;
int
err
;
d
=
debugfs_create_dir
(
"clock"
,
NULL
);
if
(
!
d
)
return
-
ENOMEM
;
clk_debugfs_root
=
d
;
list_for_each_entry
(
c
,
&
clock_list
,
node
)
{
err
=
clk_debugfs_register
(
c
);
if
(
err
)
goto
err_out
;
}
return
0
;
err_out:
debugfs_remove_recursive
(
clk_debugfs_root
);
return
err
;
}
late_initcall
(
clk_debugfs_init
);
include/linux/sh_clk.h
0 → 100644
浏览文件 @
c5eb5b37
#ifndef __SH_CLOCK_H
#define __SH_CLOCK_H
#include <linux/list.h>
#include <linux/seq_file.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/err.h>
struct
clk
;
struct
clk_ops
{
void
(
*
init
)(
struct
clk
*
clk
);
int
(
*
enable
)(
struct
clk
*
clk
);
void
(
*
disable
)(
struct
clk
*
clk
);
unsigned
long
(
*
recalc
)(
struct
clk
*
clk
);
int
(
*
set_rate
)(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
);
int
(
*
set_parent
)(
struct
clk
*
clk
,
struct
clk
*
parent
);
long
(
*
round_rate
)(
struct
clk
*
clk
,
unsigned
long
rate
);
};
struct
clk
{
struct
list_head
node
;
const
char
*
name
;
int
id
;
struct
clk
*
parent
;
struct
clk_ops
*
ops
;
struct
list_head
children
;
struct
list_head
sibling
;
/* node for children */
int
usecount
;
unsigned
long
rate
;
unsigned
long
flags
;
void
__iomem
*
enable_reg
;
unsigned
int
enable_bit
;
unsigned
long
arch_flags
;
void
*
priv
;
struct
dentry
*
dentry
;
struct
cpufreq_frequency_table
*
freq_table
;
};
#define CLK_ENABLE_ON_INIT (1 << 0)
/* arch/sh/kernel/cpu/clock.c */
unsigned
long
followparent_recalc
(
struct
clk
*
);
void
recalculate_root_clocks
(
void
);
void
propagate_rate
(
struct
clk
*
);
int
clk_reparent
(
struct
clk
*
child
,
struct
clk
*
parent
);
int
clk_register
(
struct
clk
*
);
void
clk_unregister
(
struct
clk
*
);
void
clk_enable_init_clocks
(
void
);
/* the exported API, in addition to clk_set_rate */
/**
* clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
* @clk: clock source
* @rate: desired clock rate in Hz
* @algo_id: algorithm id to be passed down to ops->set_rate
*
* Returns success (0) or negative errno.
*/
int
clk_set_rate_ex
(
struct
clk
*
clk
,
unsigned
long
rate
,
int
algo_id
);
enum
clk_sh_algo_id
{
NO_CHANGE
=
0
,
IUS_N1_N1
,
IUS_322
,
IUS_522
,
IUS_N11
,
SB_N1
,
SB3_N1
,
SB3_32
,
SB3_43
,
SB3_54
,
BP_N1
,
IP_N1
,
};
struct
clk_div_mult_table
{
unsigned
int
*
divisors
;
unsigned
int
nr_divisors
;
unsigned
int
*
multipliers
;
unsigned
int
nr_multipliers
;
};
struct
cpufreq_frequency_table
;
void
clk_rate_table_build
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
int
nr_freqs
,
struct
clk_div_mult_table
*
src_table
,
unsigned
long
*
bitmap
);
long
clk_rate_table_round
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
);
int
clk_rate_table_find
(
struct
clk
*
clk
,
struct
cpufreq_frequency_table
*
freq_table
,
unsigned
long
rate
);
#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \
{ \
.parent = _parent, \
.enable_reg = (void __iomem *)_enable_reg, \
.enable_bit = _enable_bit, \
.flags = _flags, \
}
int
sh_clk_mstp32_register
(
struct
clk
*
clks
,
int
nr
);
#define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \
{ \
.parent = _parent, \
.enable_reg = (void __iomem *)_reg, \
.enable_bit = _shift, \
.arch_flags = _div_bitmap, \
.flags = _flags, \
}
struct
clk_div4_table
{
struct
clk_div_mult_table
*
div_mult_table
;
void
(
*
kick
)(
struct
clk
*
clk
);
};
int
sh_clk_div4_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
);
int
sh_clk_div4_enable_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
);
int
sh_clk_div4_reparent_register
(
struct
clk
*
clks
,
int
nr
,
struct
clk_div4_table
*
table
);
#define SH_CLK_DIV6(_parent, _reg, _flags) \
{ \
.parent = _parent, \
.enable_reg = (void __iomem *)_reg, \
.flags = _flags, \
}
int
sh_clk_div6_register
(
struct
clk
*
clks
,
int
nr
);
#endif
/* __SH_CLOCK_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录