Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c6906c3e
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c6906c3e
编写于
1月 03, 2011
作者:
K
Kukjin Kim
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next-s5pv310' into for-next
Conflicts: arch/arm/mach-s5pv310/Makefile
上级
285dee7f
8267e2e0
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
711 addition
and
9 deletion
+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
未找到文件。
arch/arm/Kconfig
浏览文件 @
c6906c3e
...
...
@@ -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
浏览文件 @
c6906c3e
...
...
@@ -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 dma.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
浏览文件 @
c6906c3e
...
...
@@ -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 */
...
...
@@ -1020,6 +1020,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
;
...
...
@@ -1043,6 +1054,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
);
...
...
@@ -1056,7 +1070,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
浏览文件 @
c6906c3e
...
...
@@ -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
浏览文件 @
c6906c3e
/* 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
浏览文件 @
c6906c3e
...
...
@@ -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
浏览文件 @
c6906c3e
...
...
@@ -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
浏览文件 @
c6906c3e
/* 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 */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录