Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c5eb5b37
Commit
c5eb5b37
authored
May 13, 2010
by
Paul Mundt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sh/clkfwk'
parents
15f2a796
f5ca6d4c
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1698 additions
and
1326 deletions
+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
No files found.
arch/sh/boards/mach-ecovec24/setup.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment