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
nexedi
linux
Commits
8267e2e0
Commit
8267e2e0
authored
Jan 03, 2011
by
Kukjin Kim
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev/s5pv310-cpufreq' into next-s5pv310
parents
fa353e9f
b333fb16
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
711 additions
and
9 deletions
+711
-9
arch/arm/Kconfig
arch/arm/Kconfig
+1
-0
arch/arm/mach-s5pv310/Makefile
arch/arm/mach-s5pv310/Makefile
+1
-0
arch/arm/mach-s5pv310/clock.c
arch/arm/mach-s5pv310/clock.c
+21
-7
arch/arm/mach-s5pv310/cpu.c
arch/arm/mach-s5pv310/cpu.c
+5
-0
arch/arm/mach-s5pv310/cpufreq.c
arch/arm/mach-s5pv310/cpufreq.c
+580
-0
arch/arm/mach-s5pv310/include/mach/map.h
arch/arm/mach-s5pv310/include/mach/map.h
+2
-0
arch/arm/mach-s5pv310/include/mach/regs-clock.h
arch/arm/mach-s5pv310/include/mach/regs-clock.h
+78
-2
arch/arm/mach-s5pv310/include/mach/regs-mem.h
arch/arm/mach-s5pv310/include/mach/regs-mem.h
+23
-0
No files found.
arch/arm/Kconfig
View file @
8267e2e0
...
...
@@ -738,6 +738,7 @@ config ARCH_S5PV310
select ARCH_SPARSEMEM_ENABLE
select GENERIC_GPIO
select HAVE_CLK
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select HAVE_S3C_RTC if RTC_CLASS
select HAVE_S3C2410_I2C if I2C
...
...
arch/arm/mach-s5pv310/Makefile
View file @
8267e2e0
...
...
@@ -14,6 +14,7 @@ obj- :=
obj-$(CONFIG_CPU_S5PV310)
+=
cpu.o init.o clock.o irq-combiner.o
obj-$(CONFIG_CPU_S5PV310)
+=
setup-i2c0.o time.o gpiolib.o irq-eint.o
obj-$(CONFIG_CPU_FREQ)
+=
cpufreq.o
obj-$(CONFIG_SMP)
+=
platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS)
+=
localtimer.o
...
...
arch/arm/mach-s5pv310/clock.c
View file @
8267e2e0
...
...
@@ -244,7 +244,7 @@ static struct clksrc_clk clk_mout_corebus = {
.
id
=
-
1
,
},
.
sources
=
&
clkset_mout_corebus
,
.
reg_src
=
{
.
reg
=
S5P_CLKSRC_
CORE
,
.
shift
=
4
,
.
size
=
1
},
.
reg_src
=
{
.
reg
=
S5P_CLKSRC_
DMC
,
.
shift
=
4
,
.
size
=
1
},
};
static
struct
clksrc_clk
clk_sclk_dmc
=
{
...
...
@@ -253,7 +253,7 @@ static struct clksrc_clk clk_sclk_dmc = {
.
id
=
-
1
,
.
parent
=
&
clk_mout_corebus
.
clk
,
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
CORE
0
,
.
shift
=
12
,
.
size
=
3
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
DMC
0
,
.
shift
=
12
,
.
size
=
3
},
};
static
struct
clksrc_clk
clk_aclk_cored
=
{
...
...
@@ -262,7 +262,7 @@ static struct clksrc_clk clk_aclk_cored = {
.
id
=
-
1
,
.
parent
=
&
clk_sclk_dmc
.
clk
,
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
CORE
0
,
.
shift
=
16
,
.
size
=
3
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
DMC
0
,
.
shift
=
16
,
.
size
=
3
},
};
static
struct
clksrc_clk
clk_aclk_corep
=
{
...
...
@@ -271,7 +271,7 @@ static struct clksrc_clk clk_aclk_corep = {
.
id
=
-
1
,
.
parent
=
&
clk_aclk_cored
.
clk
,
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
CORE
0
,
.
shift
=
20
,
.
size
=
3
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
DMC
0
,
.
shift
=
20
,
.
size
=
3
},
};
static
struct
clksrc_clk
clk_aclk_acp
=
{
...
...
@@ -280,7 +280,7 @@ static struct clksrc_clk clk_aclk_acp = {
.
id
=
-
1
,
.
parent
=
&
clk_mout_corebus
.
clk
,
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
CORE
0
,
.
shift
=
0
,
.
size
=
3
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
DMC
0
,
.
shift
=
0
,
.
size
=
3
},
};
static
struct
clksrc_clk
clk_pclk_acp
=
{
...
...
@@ -289,7 +289,7 @@ static struct clksrc_clk clk_pclk_acp = {
.
id
=
-
1
,
.
parent
=
&
clk_aclk_acp
.
clk
,
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
CORE
0
,
.
shift
=
4
,
.
size
=
3
},
.
reg_div
=
{
.
reg
=
S5P_CLKDIV_
DMC
0
,
.
shift
=
4
,
.
size
=
3
},
};
/* Core list of CMU_TOP side */
...
...
@@ -990,6 +990,17 @@ static struct clksrc_clk *sysclks[] = {
&
clk_dout_mmc4
,
};
static
int
xtal_rate
;
static
unsigned
long
s5pv310_fout_apll_get_rate
(
struct
clk
*
clk
)
{
return
s5p_get_pll45xx
(
xtal_rate
,
__raw_readl
(
S5P_APLL_CON0
),
pll_4508
);
}
static
struct
clk_ops
s5pv310_fout_apll_ops
=
{
.
get_rate
=
s5pv310_fout_apll_get_rate
,
};
void
__init_or_cpufreq
s5pv310_setup_clocks
(
void
)
{
struct
clk
*
xtal_clk
;
...
...
@@ -1013,6 +1024,9 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
BUG_ON
(
IS_ERR
(
xtal_clk
));
xtal
=
clk_get_rate
(
xtal_clk
);
xtal_rate
=
xtal
;
clk_put
(
xtal_clk
);
printk
(
KERN_DEBUG
"%s: xtal is %ld
\n
"
,
__func__
,
xtal
);
...
...
@@ -1026,7 +1040,7 @@ void __init_or_cpufreq s5pv310_setup_clocks(void)
vpll
=
s5p_get_pll46xx
(
vpllsrc
,
__raw_readl
(
S5P_VPLL_CON0
),
__raw_readl
(
S5P_VPLL_CON1
),
pll_4650
);
clk_fout_apll
.
rate
=
apll
;
clk_fout_apll
.
ops
=
&
s5pv310_fout_apll_ops
;
clk_fout_mpll
.
rate
=
mpll
;
clk_fout_epll
.
rate
=
epll
;
clk_fout_vpll
.
rate
=
vpll
;
...
...
arch/arm/mach-s5pv310/cpu.c
View file @
8267e2e0
...
...
@@ -77,6 +77,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = {
.
pfn
=
__phys_to_pfn
(
S5PV310_PA_GPIO3
),
.
length
=
SZ_256
,
.
type
=
MT_DEVICE
,
},
{
.
virtual
=
(
unsigned
long
)
S5P_VA_DMC0
,
.
pfn
=
__phys_to_pfn
(
S5PV310_PA_DMC0
),
.
length
=
SZ_4K
,
.
type
=
MT_DEVICE
,
},
{
.
virtual
=
(
unsigned
long
)
S3C_VA_UART
,
.
pfn
=
__phys_to_pfn
(
S3C_PA_UART
),
...
...
arch/arm/mach-s5pv310/cpufreq.c
0 → 100644
View file @
8267e2e0
/* linux/arch/arm/mach-s5pv310/cpufreq.c
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - CPU frequency scaling support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/cpufreq.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-mem.h>
#include <plat/clock.h>
#include <plat/pm.h>
static
struct
clk
*
cpu_clk
;
static
struct
clk
*
moutcore
;
static
struct
clk
*
mout_mpll
;
static
struct
clk
*
mout_apll
;
#ifdef CONFIG_REGULATOR
static
struct
regulator
*
arm_regulator
;
static
struct
regulator
*
int_regulator
;
#endif
static
struct
cpufreq_freqs
freqs
;
static
unsigned
int
memtype
;
enum
s5pv310_memory_type
{
DDR2
=
4
,
LPDDR2
,
DDR3
,
};
enum
cpufreq_level_index
{
L0
,
L1
,
L2
,
L3
,
CPUFREQ_LEVEL_END
,
};
static
struct
cpufreq_frequency_table
s5pv310_freq_table
[]
=
{
{
L0
,
1000
*
1000
},
{
L1
,
800
*
1000
},
{
L2
,
400
*
1000
},
{
L3
,
100
*
1000
},
{
0
,
CPUFREQ_TABLE_END
},
};
static
unsigned
int
clkdiv_cpu0
[
CPUFREQ_LEVEL_END
][
7
]
=
{
/*
* Clock divider value for following
* { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH,
* DIVATB, DIVPCLK_DBG, DIVAPLL }
*/
/* ARM L0: 1000MHz */
{
0
,
3
,
7
,
3
,
3
,
0
,
1
},
/* ARM L1: 800MHz */
{
0
,
3
,
7
,
3
,
3
,
0
,
1
},
/* ARM L2: 400MHz */
{
0
,
1
,
3
,
1
,
3
,
0
,
1
},
/* ARM L3: 100MHz */
{
0
,
0
,
1
,
0
,
3
,
1
,
1
},
};
static
unsigned
int
clkdiv_cpu1
[
CPUFREQ_LEVEL_END
][
2
]
=
{
/*
* Clock divider value for following
* { DIVCOPY, DIVHPM }
*/
/* ARM L0: 1000MHz */
{
3
,
0
},
/* ARM L1: 800MHz */
{
3
,
0
},
/* ARM L2: 400MHz */
{
3
,
0
},
/* ARM L3: 100MHz */
{
3
,
0
},
};
static
unsigned
int
clkdiv_dmc0
[
CPUFREQ_LEVEL_END
][
8
]
=
{
/*
* Clock divider value for following
* { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD
* DIVDMCP, DIVCOPY2, DIVCORE_TIMERS }
*/
/* DMC L0: 400MHz */
{
3
,
1
,
1
,
1
,
1
,
1
,
3
,
1
},
/* DMC L1: 400MHz */
{
3
,
1
,
1
,
1
,
1
,
1
,
3
,
1
},
/* DMC L2: 266.7MHz */
{
7
,
1
,
1
,
2
,
1
,
1
,
3
,
1
},
/* DMC L3: 200MHz */
{
7
,
1
,
1
,
3
,
1
,
1
,
3
,
1
},
};
static
unsigned
int
clkdiv_top
[
CPUFREQ_LEVEL_END
][
5
]
=
{
/*
* Clock divider value for following
* { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND }
*/
/* ACLK200 L0: 200MHz */
{
3
,
7
,
4
,
5
,
1
},
/* ACLK200 L1: 200MHz */
{
3
,
7
,
4
,
5
,
1
},
/* ACLK200 L2: 160MHz */
{
4
,
7
,
5
,
7
,
1
},
/* ACLK200 L3: 133.3MHz */
{
5
,
7
,
7
,
7
,
1
},
};
static
unsigned
int
clkdiv_lr_bus
[
CPUFREQ_LEVEL_END
][
2
]
=
{
/*
* Clock divider value for following
* { DIVGDL/R, DIVGPL/R }
*/
/* ACLK_GDL/R L0: 200MHz */
{
3
,
1
},
/* ACLK_GDL/R L1: 200MHz */
{
3
,
1
},
/* ACLK_GDL/R L2: 160MHz */
{
4
,
1
},
/* ACLK_GDL/R L3: 133.3MHz */
{
5
,
1
},
};
struct
cpufreq_voltage_table
{
unsigned
int
index
;
/* any */
unsigned
int
arm_volt
;
/* uV */
unsigned
int
int_volt
;
};
static
struct
cpufreq_voltage_table
s5pv310_volt_table
[
CPUFREQ_LEVEL_END
]
=
{
{
.
index
=
L0
,
.
arm_volt
=
1200000
,
.
int_volt
=
1100000
,
},
{
.
index
=
L1
,
.
arm_volt
=
1100000
,
.
int_volt
=
1100000
,
},
{
.
index
=
L2
,
.
arm_volt
=
1000000
,
.
int_volt
=
1000000
,
},
{
.
index
=
L3
,
.
arm_volt
=
900000
,
.
int_volt
=
1000000
,
},
};
static
unsigned
int
s5pv310_apll_pms_table
[
CPUFREQ_LEVEL_END
]
=
{
/* APLL FOUT L0: 1000MHz */
((
250
<<
16
)
|
(
6
<<
8
)
|
1
),
/* APLL FOUT L1: 800MHz */
((
200
<<
16
)
|
(
6
<<
8
)
|
1
),
/* APLL FOUT L2 : 400MHz */
((
200
<<
16
)
|
(
6
<<
8
)
|
2
),
/* APLL FOUT L3: 100MHz */
((
200
<<
16
)
|
(
6
<<
8
)
|
4
),
};
int
s5pv310_verify_speed
(
struct
cpufreq_policy
*
policy
)
{
return
cpufreq_frequency_table_verify
(
policy
,
s5pv310_freq_table
);
}
unsigned
int
s5pv310_getspeed
(
unsigned
int
cpu
)
{
return
clk_get_rate
(
cpu_clk
)
/
1000
;
}
void
s5pv310_set_clkdiv
(
unsigned
int
div_index
)
{
unsigned
int
tmp
;
/* Change Divider - CPU0 */
tmp
=
__raw_readl
(
S5P_CLKDIV_CPU
);
tmp
&=
~
(
S5P_CLKDIV_CPU0_CORE_MASK
|
S5P_CLKDIV_CPU0_COREM0_MASK
|
S5P_CLKDIV_CPU0_COREM1_MASK
|
S5P_CLKDIV_CPU0_PERIPH_MASK
|
S5P_CLKDIV_CPU0_ATB_MASK
|
S5P_CLKDIV_CPU0_PCLKDBG_MASK
|
S5P_CLKDIV_CPU0_APLL_MASK
);
tmp
|=
((
clkdiv_cpu0
[
div_index
][
0
]
<<
S5P_CLKDIV_CPU0_CORE_SHIFT
)
|
(
clkdiv_cpu0
[
div_index
][
1
]
<<
S5P_CLKDIV_CPU0_COREM0_SHIFT
)
|
(
clkdiv_cpu0
[
div_index
][
2
]
<<
S5P_CLKDIV_CPU0_COREM1_SHIFT
)
|
(
clkdiv_cpu0
[
div_index
][
3
]
<<
S5P_CLKDIV_CPU0_PERIPH_SHIFT
)
|
(
clkdiv_cpu0
[
div_index
][
4
]
<<
S5P_CLKDIV_CPU0_ATB_SHIFT
)
|
(
clkdiv_cpu0
[
div_index
][
5
]
<<
S5P_CLKDIV_CPU0_PCLKDBG_SHIFT
)
|
(
clkdiv_cpu0
[
div_index
][
6
]
<<
S5P_CLKDIV_CPU0_APLL_SHIFT
));
__raw_writel
(
tmp
,
S5P_CLKDIV_CPU
);
do
{
tmp
=
__raw_readl
(
S5P_CLKDIV_STATCPU
);
}
while
(
tmp
&
0x1111111
);
/* Change Divider - CPU1 */
tmp
=
__raw_readl
(
S5P_CLKDIV_CPU1
);
tmp
&=
~
((
0x7
<<
4
)
|
0x7
);
tmp
|=
((
clkdiv_cpu1
[
div_index
][
0
]
<<
4
)
|
(
clkdiv_cpu1
[
div_index
][
1
]
<<
0
));
__raw_writel
(
tmp
,
S5P_CLKDIV_CPU1
);
do
{
tmp
=
__raw_readl
(
S5P_CLKDIV_STATCPU1
);
}
while
(
tmp
&
0x11
);
/* Change Divider - DMC0 */
tmp
=
__raw_readl
(
S5P_CLKDIV_DMC0
);
tmp
&=
~
(
S5P_CLKDIV_DMC0_ACP_MASK
|
S5P_CLKDIV_DMC0_ACPPCLK_MASK
|
S5P_CLKDIV_DMC0_DPHY_MASK
|
S5P_CLKDIV_DMC0_DMC_MASK
|
S5P_CLKDIV_DMC0_DMCD_MASK
|
S5P_CLKDIV_DMC0_DMCP_MASK
|
S5P_CLKDIV_DMC0_COPY2_MASK
|
S5P_CLKDIV_DMC0_CORETI_MASK
);
tmp
|=
((
clkdiv_dmc0
[
div_index
][
0
]
<<
S5P_CLKDIV_DMC0_ACP_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
1
]
<<
S5P_CLKDIV_DMC0_ACPPCLK_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
2
]
<<
S5P_CLKDIV_DMC0_DPHY_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
3
]
<<
S5P_CLKDIV_DMC0_DMC_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
4
]
<<
S5P_CLKDIV_DMC0_DMCD_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
5
]
<<
S5P_CLKDIV_DMC0_DMCP_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
6
]
<<
S5P_CLKDIV_DMC0_COPY2_SHIFT
)
|
(
clkdiv_dmc0
[
div_index
][
7
]
<<
S5P_CLKDIV_DMC0_CORETI_SHIFT
));
__raw_writel
(
tmp
,
S5P_CLKDIV_DMC0
);
do
{
tmp
=
__raw_readl
(
S5P_CLKDIV_STAT_DMC0
);
}
while
(
tmp
&
0x11111111
);
/* Change Divider - TOP */
tmp
=
__raw_readl
(
S5P_CLKDIV_TOP
);
tmp
&=
~
(
S5P_CLKDIV_TOP_ACLK200_MASK
|
S5P_CLKDIV_TOP_ACLK100_MASK
|
S5P_CLKDIV_TOP_ACLK160_MASK
|
S5P_CLKDIV_TOP_ACLK133_MASK
|
S5P_CLKDIV_TOP_ONENAND_MASK
);
tmp
|=
((
clkdiv_top
[
div_index
][
0
]
<<
S5P_CLKDIV_TOP_ACLK200_SHIFT
)
|
(
clkdiv_top
[
div_index
][
1
]
<<
S5P_CLKDIV_TOP_ACLK100_SHIFT
)
|
(
clkdiv_top
[
div_index
][
2
]
<<
S5P_CLKDIV_TOP_ACLK160_SHIFT
)
|
(
clkdiv_top
[
div_index
][
3
]
<<
S5P_CLKDIV_TOP_ACLK133_SHIFT
)
|
(
clkdiv_top
[
div_index
][
4
]
<<
S5P_CLKDIV_TOP_ONENAND_SHIFT
));
__raw_writel
(
tmp
,
S5P_CLKDIV_TOP
);
do
{
tmp
=
__raw_readl
(
S5P_CLKDIV_STAT_TOP
);
}
while
(
tmp
&
0x11111
);
/* Change Divider - LEFTBUS */
tmp
=
__raw_readl
(
S5P_CLKDIV_LEFTBUS
);
tmp
&=
~
(
S5P_CLKDIV_BUS_GDLR_MASK
|
S5P_CLKDIV_BUS_GPLR_MASK
);
tmp
|=
((
clkdiv_lr_bus
[
div_index
][
0
]
<<
S5P_CLKDIV_BUS_GDLR_SHIFT
)
|
(
clkdiv_lr_bus
[
div_index
][
1
]
<<
S5P_CLKDIV_BUS_GPLR_SHIFT
));
__raw_writel
(
tmp
,
S5P_CLKDIV_LEFTBUS
);
do
{
tmp
=
__raw_readl
(
S5P_CLKDIV_STAT_LEFTBUS
);
}
while
(
tmp
&
0x11
);
/* Change Divider - RIGHTBUS */
tmp
=
__raw_readl
(
S5P_CLKDIV_RIGHTBUS
);
tmp
&=
~
(
S5P_CLKDIV_BUS_GDLR_MASK
|
S5P_CLKDIV_BUS_GPLR_MASK
);
tmp
|=
((
clkdiv_lr_bus
[
div_index
][
0
]
<<
S5P_CLKDIV_BUS_GDLR_SHIFT
)
|
(
clkdiv_lr_bus
[
div_index
][
1
]
<<
S5P_CLKDIV_BUS_GPLR_SHIFT
));
__raw_writel
(
tmp
,
S5P_CLKDIV_RIGHTBUS
);
do
{
tmp
=
__raw_readl
(
S5P_CLKDIV_STAT_RIGHTBUS
);
}
while
(
tmp
&
0x11
);
}
static
void
s5pv310_set_apll
(
unsigned
int
index
)
{
unsigned
int
tmp
;
/* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
clk_set_parent
(
moutcore
,
mout_mpll
);
do
{
tmp
=
(
__raw_readl
(
S5P_CLKMUX_STATCPU
)
>>
S5P_CLKSRC_CPU_MUXCORE_SHIFT
);
tmp
&=
0x7
;
}
while
(
tmp
!=
0x2
);
/* 2. Set APLL Lock time */
__raw_writel
(
S5P_APLL_LOCKTIME
,
S5P_APLL_LOCK
);
/* 3. Change PLL PMS values */
tmp
=
__raw_readl
(
S5P_APLL_CON0
);
tmp
&=
~
((
0x3ff
<<
16
)
|
(
0x3f
<<
8
)
|
(
0x7
<<
0
));
tmp
|=
s5pv310_apll_pms_table
[
index
];
__raw_writel
(
tmp
,
S5P_APLL_CON0
);
/* 4. wait_lock_time */
do
{
tmp
=
__raw_readl
(
S5P_APLL_CON0
);
}
while
(
!
(
tmp
&
(
0x1
<<
S5P_APLLCON0_LOCKED_SHIFT
)));
/* 5. MUX_CORE_SEL = APLL */
clk_set_parent
(
moutcore
,
mout_apll
);
do
{
tmp
=
__raw_readl
(
S5P_CLKMUX_STATCPU
);
tmp
&=
S5P_CLKMUX_STATCPU_MUXCORE_MASK
;
}
while
(
tmp
!=
(
0x1
<<
S5P_CLKSRC_CPU_MUXCORE_SHIFT
));
}
static
void
s5pv310_set_frequency
(
unsigned
int
old_index
,
unsigned
int
new_index
)
{
unsigned
int
tmp
;
if
(
old_index
>
new_index
)
{
/* The frequency changing to L0 needs to change apll */
if
(
freqs
.
new
==
s5pv310_freq_table
[
L0
].
frequency
)
{
/* 1. Change the system clock divider values */
s5pv310_set_clkdiv
(
new_index
);
/* 2. Change the apll m,p,s value */
s5pv310_set_apll
(
new_index
);
}
else
{
/* 1. Change the system clock divider values */
s5pv310_set_clkdiv
(
new_index
);
/* 2. Change just s value in apll m,p,s value */
tmp
=
__raw_readl
(
S5P_APLL_CON0
);
tmp
&=
~
(
0x7
<<
0
);
tmp
|=
(
s5pv310_apll_pms_table
[
new_index
]
&
0x7
);
__raw_writel
(
tmp
,
S5P_APLL_CON0
);
}
}
else
if
(
old_index
<
new_index
)
{
/* The frequency changing from L0 needs to change apll */
if
(
freqs
.
old
==
s5pv310_freq_table
[
L0
].
frequency
)
{
/* 1. Change the apll m,p,s value */
s5pv310_set_apll
(
new_index
);
/* 2. Change the system clock divider values */
s5pv310_set_clkdiv
(
new_index
);
}
else
{
/* 1. Change just s value in apll m,p,s value */
tmp
=
__raw_readl
(
S5P_APLL_CON0
);
tmp
&=
~
(
0x7
<<
0
);
tmp
|=
(
s5pv310_apll_pms_table
[
new_index
]
&
0x7
);
__raw_writel
(
tmp
,
S5P_APLL_CON0
);
/* 2. Change the system clock divider values */
s5pv310_set_clkdiv
(
new_index
);
}
}
}
static
int
s5pv310_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
)
{
unsigned
int
index
,
old_index
;
unsigned
int
arm_volt
,
int_volt
;
freqs
.
old
=
s5pv310_getspeed
(
policy
->
cpu
);
if
(
cpufreq_frequency_table_target
(
policy
,
s5pv310_freq_table
,
freqs
.
old
,
relation
,
&
old_index
))
return
-
EINVAL
;
if
(
cpufreq_frequency_table_target
(
policy
,
s5pv310_freq_table
,
target_freq
,
relation
,
&
index
))
return
-
EINVAL
;
freqs
.
new
=
s5pv310_freq_table
[
index
].
frequency
;
freqs
.
cpu
=
policy
->
cpu
;
if
(
freqs
.
new
==
freqs
.
old
)
return
0
;
/* get the voltage value */
arm_volt
=
s5pv310_volt_table
[
index
].
arm_volt
;
int_volt
=
s5pv310_volt_table
[
index
].
int_volt
;
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_PRECHANGE
);
/* control regulator */
if
(
freqs
.
new
>
freqs
.
old
)
{
/* Voltage up */
#ifdef CONFIG_REGULATOR
regulator_set_voltage
(
arm_regulator
,
arm_volt
,
arm_volt
);
regulator_set_voltage
(
int_regulator
,
int_volt
,
int_volt
);
#endif
}
/* Clock Configuration Procedure */
s5pv310_set_frequency
(
old_index
,
index
);
/* control regulator */
if
(
freqs
.
new
<
freqs
.
old
)
{
/* Voltage down */
#ifdef CONFIG_REGULATOR
regulator_set_voltage
(
arm_regulator
,
arm_volt
,
arm_volt
);
regulator_set_voltage
(
int_regulator
,
int_volt
,
int_volt
);
#endif
}
cpufreq_notify_transition
(
&
freqs
,
CPUFREQ_POSTCHANGE
);
return
0
;
}
#ifdef CONFIG_PM
static
int
s5pv310_cpufreq_suspend
(
struct
cpufreq_policy
*
policy
,
pm_message_t
pmsg
)
{
return
0
;
}
static
int
s5pv310_cpufreq_resume
(
struct
cpufreq_policy
*
policy
)
{
return
0
;
}
#endif
static
int
s5pv310_cpufreq_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
policy
->
cur
=
policy
->
min
=
policy
->
max
=
s5pv310_getspeed
(
policy
->
cpu
);
cpufreq_frequency_table_get_attr
(
s5pv310_freq_table
,
policy
->
cpu
);
/* set the transition latency value */
policy
->
cpuinfo
.
transition_latency
=
100000
;
/*
* S5PV310 multi-core processors has 2 cores
* that the frequency cannot be set independently.
* Each cpu is bound to the same speed.
* So the affected cpu is all of the cpus.
*/
cpumask_setall
(
policy
->
cpus
);
return
cpufreq_frequency_table_cpuinfo
(
policy
,
s5pv310_freq_table
);
}
static
struct
cpufreq_driver
s5pv310_driver
=
{
.
flags
=
CPUFREQ_STICKY
,
.
verify
=
s5pv310_verify_speed
,
.
target
=
s5pv310_target
,
.
get
=
s5pv310_getspeed
,
.
init
=
s5pv310_cpufreq_cpu_init
,
.
name
=
"s5pv310_cpufreq"
,
#ifdef CONFIG_PM
.
suspend
=
s5pv310_cpufreq_suspend
,
.
resume
=
s5pv310_cpufreq_resume
,
#endif
};
static
int
__init
s5pv310_cpufreq_init
(
void
)
{
cpu_clk
=
clk_get
(
NULL
,
"armclk"
);
if
(
IS_ERR
(
cpu_clk
))
return
PTR_ERR
(
cpu_clk
);
moutcore
=
clk_get
(
NULL
,
"moutcore"
);
if
(
IS_ERR
(
moutcore
))
goto
out
;
mout_mpll
=
clk_get
(
NULL
,
"mout_mpll"
);
if
(
IS_ERR
(
mout_mpll
))
goto
out
;
mout_apll
=
clk_get
(
NULL
,
"mout_apll"
);
if
(
IS_ERR
(
mout_apll
))
goto
out
;
#ifdef CONFIG_REGULATOR
arm_regulator
=
regulator_get
(
NULL
,
"vdd_arm"
);
if
(
IS_ERR
(
arm_regulator
))
{
printk
(
KERN_ERR
"failed to get resource %s
\n
"
,
"vdd_arm"
);
goto
out
;
}
int_regulator
=
regulator_get
(
NULL
,
"vdd_int"
);
if
(
IS_ERR
(
int_regulator
))
{
printk
(
KERN_ERR
"failed to get resource %s
\n
"
,
"vdd_int"
);
goto
out
;
}
#endif
/*
* Check DRAM type.
* Because DVFS level is different according to DRAM type.
*/
memtype
=
__raw_readl
(
S5P_VA_DMC0
+
S5P_DMC0_MEMCON_OFFSET
);
memtype
=
(
memtype
>>
S5P_DMC0_MEMTYPE_SHIFT
);
memtype
&=
S5P_DMC0_MEMTYPE_MASK
;
if
((
memtype
<
DDR2
)
&&
(
memtype
>
DDR3
))
{
printk
(
KERN_ERR
"%s: wrong memtype= 0x%x
\n
"
,
__func__
,
memtype
);
goto
out
;
}
else
{
printk
(
KERN_DEBUG
"%s: memtype= 0x%x
\n
"
,
__func__
,
memtype
);
}
return
cpufreq_register_driver
(
&
s5pv310_driver
);
out:
if
(
!
IS_ERR
(
cpu_clk
))
clk_put
(
cpu_clk
);
if
(
!
IS_ERR
(
moutcore
))
clk_put
(
moutcore
);
if
(
!
IS_ERR
(
mout_mpll
))
clk_put
(
mout_mpll
);
if
(
!
IS_ERR
(
mout_apll
))
clk_put
(
mout_apll
);
#ifdef CONFIG_REGULATOR
if
(
!
IS_ERR
(
arm_regulator
))
regulator_put
(
arm_regulator
);
if
(
!
IS_ERR
(
int_regulator
))
regulator_put
(
int_regulator
);
#endif
printk
(
KERN_ERR
"%s: failed initialization
\n
"
,
__func__
);
return
-
EINVAL
;
}
late_initcall
(
s5pv310_cpufreq_init
);
arch/arm/mach-s5pv310/include/mach/map.h
View file @
8267e2e0
...
...
@@ -46,6 +46,8 @@
#define S5PV310_PA_WATCHDOG (0x10060000)
#define S5PV310_PA_RTC (0x10070000)
#define S5PV310_PA_DMC0 (0x10400000)
#define S5PV310_PA_COMBINER (0x10448000)
#define S5PV310_PA_COREPERI (0x10500000)
...
...
arch/arm/mach-s5pv310/include/mach/regs-clock.h
View file @
8267e2e0
...
...
@@ -19,6 +19,12 @@
#define S5P_INFORM0 S5P_CLKREG(0x800)
#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
#define S5P_VPLL_CON0 S5P_CLKREG(0x0C120)
...
...
@@ -58,6 +64,8 @@
#define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350)
#define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354)
#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610)
#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
#define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934)
...
...
@@ -66,8 +74,9 @@
#define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950)
#define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960)
#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200)
#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500)
#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200)
#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500)
#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600)
#define S5P_APLL_LOCK S5P_CLKREG(0x14000)
#define S5P_MPLL_LOCK S5P_CLKREG(0x14004)
...
...
@@ -80,10 +89,77 @@
#define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400)
#define S5P_CLKDIV_CPU S5P_CLKREG(0x14500)
#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504)
#define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600)
#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604)
#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
/* APLL_LOCK */
#define S5P_APLL_LOCKTIME (0x1C20)
/* 300us */
/* APLL_CON0 */
#define S5P_APLLCON0_ENABLE_SHIFT (31)
#define S5P_APLLCON0_LOCKED_SHIFT (29)
#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
/* CLK_SRC_CPU */
#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
/* CLKDIV_CPU0 */
#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT)
#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8)
#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT)
#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12)
#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT)
#define S5P_CLKDIV_CPU0_ATB_SHIFT (16)
#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT)
#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20)
#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT)
#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
/* CLKDIV_DMC0 */
#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT)
#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8)
#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT)
#define S5P_CLKDIV_DMC0_DMC_SHIFT (12)
#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT)
#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16)
#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT)
#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20)
#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT)
#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24)
#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT)
#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
/* CLKDIV_TOP */
#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT)
#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8)
#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT)
#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12)
#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT)
#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/
#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
/* Compatibility defines */
#define S5P_EPLL_CON S5P_EPLL_CON0
...
...
arch/arm/mach-s5pv310/include/mach/regs-mem.h
0 → 100644
View file @
8267e2e0
/* linux/arch/arm/mach-s5pv310/include/mach/regs-mem.h
*
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* S5PV310 - SROMC and DMC register definitions
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_REGS_MEM_H
#define __ASM_ARCH_REGS_MEM_H __FILE__
#include <mach/map.h>
#define S5P_DMC0_MEMCON_OFFSET 0x04
#define S5P_DMC0_MEMTYPE_SHIFT 8
#define S5P_DMC0_MEMTYPE_MASK 0xF
#endif
/* __ASM_ARCH_REGS_MEM_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