Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
96607113
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
96607113
编写于
5月 18, 2018
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge back cpufreq material for v4.18.
上级
0cf442c6
144ec880
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
178 addition
and
52 deletion
+178
-52
drivers/cpufreq/armada-37xx-cpufreq.c
drivers/cpufreq/armada-37xx-cpufreq.c
+87
-13
drivers/cpufreq/cpufreq-dt-platdev.c
drivers/cpufreq/cpufreq-dt-platdev.c
+0
-2
drivers/cpufreq/cpufreq-dt.c
drivers/cpufreq/cpufreq-dt.c
+8
-2
drivers/cpufreq/cpufreq-dt.h
drivers/cpufreq/cpufreq-dt.h
+5
-0
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+32
-31
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/intel_pstate.c
+44
-2
drivers/cpufreq/s3c2440-cpufreq.c
drivers/cpufreq/s3c2440-cpufreq.c
+1
-1
drivers/cpufreq/speedstep-lib.c
drivers/cpufreq/speedstep-lib.c
+1
-1
未找到文件。
drivers/cpufreq/armada-37xx-cpufreq.c
浏览文件 @
96607113
...
...
@@ -23,6 +23,8 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include "cpufreq-dt.h"
/* Power management in North Bridge register set */
#define ARMADA_37XX_NB_L0L1 0x18
#define ARMADA_37XX_NB_L2L3 0x1C
...
...
@@ -56,6 +58,16 @@
*/
#define LOAD_LEVEL_NR 4
struct
armada37xx_cpufreq_state
{
struct
regmap
*
regmap
;
u32
nb_l0l1
;
u32
nb_l2l3
;
u32
nb_dyn_mod
;
u32
nb_cpu_load
;
};
static
struct
armada37xx_cpufreq_state
*
armada37xx_cpufreq_state
;
struct
armada_37xx_dvfs
{
u32
cpu_freq_max
;
u8
divider
[
LOAD_LEVEL_NR
];
...
...
@@ -136,7 +148,7 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
clk_set_parent
(
clk
,
parent
);
}
static
void
__init
armada37xx_cpufreq_disable_dvfs
(
struct
regmap
*
base
)
static
void
armada37xx_cpufreq_disable_dvfs
(
struct
regmap
*
base
)
{
unsigned
int
reg
=
ARMADA_37XX_NB_DYN_MOD
,
mask
=
ARMADA_37XX_NB_DFS_EN
;
...
...
@@ -162,10 +174,47 @@ static void __init armada37xx_cpufreq_enable_dvfs(struct regmap *base)
regmap_update_bits
(
base
,
reg
,
mask
,
mask
);
}
static
int
armada37xx_cpufreq_suspend
(
struct
cpufreq_policy
*
policy
)
{
struct
armada37xx_cpufreq_state
*
state
=
armada37xx_cpufreq_state
;
regmap_read
(
state
->
regmap
,
ARMADA_37XX_NB_L0L1
,
&
state
->
nb_l0l1
);
regmap_read
(
state
->
regmap
,
ARMADA_37XX_NB_L2L3
,
&
state
->
nb_l2l3
);
regmap_read
(
state
->
regmap
,
ARMADA_37XX_NB_CPU_LOAD
,
&
state
->
nb_cpu_load
);
regmap_read
(
state
->
regmap
,
ARMADA_37XX_NB_DYN_MOD
,
&
state
->
nb_dyn_mod
);
return
0
;
}
static
int
armada37xx_cpufreq_resume
(
struct
cpufreq_policy
*
policy
)
{
struct
armada37xx_cpufreq_state
*
state
=
armada37xx_cpufreq_state
;
/* Ensure DVFS is disabled otherwise the following registers are RO */
armada37xx_cpufreq_disable_dvfs
(
state
->
regmap
);
regmap_write
(
state
->
regmap
,
ARMADA_37XX_NB_L0L1
,
state
->
nb_l0l1
);
regmap_write
(
state
->
regmap
,
ARMADA_37XX_NB_L2L3
,
state
->
nb_l2l3
);
regmap_write
(
state
->
regmap
,
ARMADA_37XX_NB_CPU_LOAD
,
state
->
nb_cpu_load
);
/*
* NB_DYN_MOD register is the one that actually enable back DVFS if it
* was enabled before the suspend operation. This must be done last
* otherwise other registers are not writable.
*/
regmap_write
(
state
->
regmap
,
ARMADA_37XX_NB_DYN_MOD
,
state
->
nb_dyn_mod
);
return
0
;
}
static
int
__init
armada37xx_cpufreq_driver_init
(
void
)
{
struct
cpufreq_dt_platform_data
pdata
;
struct
armada_37xx_dvfs
*
dvfs
;
struct
platform_device
*
pdev
;
unsigned
long
freq
;
unsigned
int
cur_frequency
;
struct
regmap
*
nb_pm_base
;
struct
device
*
cpu_dev
;
...
...
@@ -207,33 +256,58 @@ static int __init armada37xx_cpufreq_driver_init(void)
}
dvfs
=
armada_37xx_cpu_freq_info_get
(
cur_frequency
);
if
(
!
dvfs
)
if
(
!
dvfs
)
{
clk_put
(
clk
);
return
-
EINVAL
;
}
armada37xx_cpufreq_state
=
kmalloc
(
sizeof
(
*
armada37xx_cpufreq_state
),
GFP_KERNEL
);
if
(
!
armada37xx_cpufreq_state
)
{
clk_put
(
clk
);
return
-
ENOMEM
;
}
armada37xx_cpufreq_state
->
regmap
=
nb_pm_base
;
armada37xx_cpufreq_dvfs_setup
(
nb_pm_base
,
clk
,
dvfs
->
divider
);
clk_put
(
clk
);
for
(
load_lvl
=
ARMADA_37XX_DVFS_LOAD_0
;
load_lvl
<
LOAD_LEVEL_NR
;
load_lvl
++
)
{
unsigned
long
freq
=
cur_frequency
/
dvfs
->
divider
[
load_lvl
];
freq
=
cur_frequency
/
dvfs
->
divider
[
load_lvl
];
ret
=
dev_pm_opp_add
(
cpu_dev
,
freq
,
0
);
if
(
ret
)
{
/* clean-up the already added opp before leaving */
while
(
load_lvl
--
>
ARMADA_37XX_DVFS_LOAD_0
)
{
freq
=
cur_frequency
/
dvfs
->
divider
[
load_lvl
];
dev_pm_opp_remove
(
cpu_dev
,
freq
);
}
return
ret
;
}
if
(
ret
)
goto
remove_opp
;
}
/* Now that everything is setup, enable the DVFS at hardware level */
armada37xx_cpufreq_enable_dvfs
(
nb_pm_base
);
pdev
=
platform_device_register_simple
(
"cpufreq-dt"
,
-
1
,
NULL
,
0
);
pdata
.
suspend
=
armada37xx_cpufreq_suspend
;
pdata
.
resume
=
armada37xx_cpufreq_resume
;
pdev
=
platform_device_register_data
(
NULL
,
"cpufreq-dt"
,
-
1
,
&
pdata
,
sizeof
(
pdata
));
ret
=
PTR_ERR_OR_ZERO
(
pdev
);
if
(
ret
)
goto
disable_dvfs
;
return
0
;
disable_dvfs:
armada37xx_cpufreq_disable_dvfs
(
nb_pm_base
);
remove_opp:
/* clean-up the already added opp before leaving */
while
(
load_lvl
--
>
ARMADA_37XX_DVFS_LOAD_0
)
{
freq
=
cur_frequency
/
dvfs
->
divider
[
load_lvl
];
dev_pm_opp_remove
(
cpu_dev
,
freq
);
}
kfree
(
armada37xx_cpufreq_state
);
return
PTR_ERR_OR_ZERO
(
pdev
)
;
return
ret
;
}
/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
late_initcall
(
armada37xx_cpufreq_driver_init
);
...
...
drivers/cpufreq/cpufreq-dt-platdev.c
浏览文件 @
96607113
...
...
@@ -66,8 +66,6 @@ static const struct of_device_id whitelist[] __initconst = {
{
.
compatible
=
"renesas,r8a7792"
,
},
{
.
compatible
=
"renesas,r8a7793"
,
},
{
.
compatible
=
"renesas,r8a7794"
,
},
{
.
compatible
=
"renesas,r8a7795"
,
},
{
.
compatible
=
"renesas,r8a7796"
,
},
{
.
compatible
=
"renesas,sh73a0"
,
},
{
.
compatible
=
"rockchip,rk2928"
,
},
...
...
drivers/cpufreq/cpufreq-dt.c
浏览文件 @
96607113
...
...
@@ -346,8 +346,14 @@ static int dt_cpufreq_probe(struct platform_device *pdev)
if
(
ret
)
return
ret
;
if
(
data
&&
data
->
have_governor_per_policy
)
dt_cpufreq_driver
.
flags
|=
CPUFREQ_HAVE_GOVERNOR_PER_POLICY
;
if
(
data
)
{
if
(
data
->
have_governor_per_policy
)
dt_cpufreq_driver
.
flags
|=
CPUFREQ_HAVE_GOVERNOR_PER_POLICY
;
dt_cpufreq_driver
.
resume
=
data
->
resume
;
if
(
data
->
suspend
)
dt_cpufreq_driver
.
suspend
=
data
->
suspend
;
}
ret
=
cpufreq_register_driver
(
&
dt_cpufreq_driver
);
if
(
ret
)
...
...
drivers/cpufreq/cpufreq-dt.h
浏览文件 @
96607113
...
...
@@ -12,8 +12,13 @@
#include <linux/types.h>
struct
cpufreq_policy
;
struct
cpufreq_dt_platform_data
{
bool
have_governor_per_policy
;
int
(
*
suspend
)(
struct
cpufreq_policy
*
policy
);
int
(
*
resume
)(
struct
cpufreq_policy
*
policy
);
};
#endif
/* __CPUFREQ_DT_H__ */
drivers/cpufreq/cpufreq.c
浏览文件 @
96607113
...
...
@@ -300,8 +300,19 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
#endif
}
static
void
__cpufreq_notify_transition
(
struct
cpufreq_policy
*
policy
,
struct
cpufreq_freqs
*
freqs
,
unsigned
int
state
)
/**
* cpufreq_notify_transition - Notify frequency transition and adjust_jiffies.
* @policy: cpufreq policy to enable fast frequency switching for.
* @freqs: contain details of the frequency update.
* @state: set to CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
*
* This function calls the transition notifiers and the "adjust_jiffies"
* function. It is called twice on all CPU frequency changes that have
* external effects.
*/
static
void
cpufreq_notify_transition
(
struct
cpufreq_policy
*
policy
,
struct
cpufreq_freqs
*
freqs
,
unsigned
int
state
)
{
BUG_ON
(
irqs_disabled
());
...
...
@@ -313,54 +324,44 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
state
,
freqs
->
new
);
switch
(
state
)
{
case
CPUFREQ_PRECHANGE
:
/* detect if the driver reported a value as "old frequency"
/*
* Detect if the driver reported a value as "old frequency"
* which is not equal to what the cpufreq core thinks is
* "old frequency".
*/
if
(
!
(
cpufreq_driver
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
if
((
policy
)
&&
(
policy
->
cpu
==
freqs
->
cpu
)
&&
(
policy
->
cur
)
&&
(
policy
->
cur
!=
freqs
->
old
))
{
if
(
policy
->
cur
&&
(
policy
->
cur
!=
freqs
->
old
))
{
pr_debug
(
"Warning: CPU frequency is %u, cpufreq assumed %u kHz
\n
"
,
freqs
->
old
,
policy
->
cur
);
freqs
->
old
=
policy
->
cur
;
}
}
srcu_notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_PRECHANGE
,
freqs
);
for_each_cpu
(
freqs
->
cpu
,
policy
->
cpus
)
{
srcu_notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_PRECHANGE
,
freqs
);
}
adjust_jiffies
(
CPUFREQ_PRECHANGE
,
freqs
);
break
;
case
CPUFREQ_POSTCHANGE
:
adjust_jiffies
(
CPUFREQ_POSTCHANGE
,
freqs
);
pr_debug
(
"FREQ: %lu - CPU: %lu
\n
"
,
(
unsigned
long
)
freqs
->
new
,
(
unsigned
long
)
freqs
->
cpu
);
trace_cpu_frequency
(
freqs
->
new
,
freqs
->
cpu
);
pr_debug
(
"FREQ: %u - CPUs: %*pbl
\n
"
,
freqs
->
new
,
cpumask_pr_args
(
policy
->
cpus
));
for_each_cpu
(
freqs
->
cpu
,
policy
->
cpus
)
{
trace_cpu_frequency
(
freqs
->
new
,
freqs
->
cpu
);
srcu_notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_POSTCHANGE
,
freqs
);
}
cpufreq_stats_record_transition
(
policy
,
freqs
->
new
);
srcu_notifier_call_chain
(
&
cpufreq_transition_notifier_list
,
CPUFREQ_POSTCHANGE
,
freqs
);
if
(
likely
(
policy
)
&&
likely
(
policy
->
cpu
==
freqs
->
cpu
))
policy
->
cur
=
freqs
->
new
;
break
;
policy
->
cur
=
freqs
->
new
;
}
}
/**
* cpufreq_notify_transition - call notifier chain and adjust_jiffies
* on frequency transition.
*
* This function calls the transition notifiers and the "adjust_jiffies"
* function. It is called twice on all CPU frequency changes that have
* external effects.
*/
static
void
cpufreq_notify_transition
(
struct
cpufreq_policy
*
policy
,
struct
cpufreq_freqs
*
freqs
,
unsigned
int
state
)
{
for_each_cpu
(
freqs
->
cpu
,
policy
->
cpus
)
__cpufreq_notify_transition
(
policy
,
freqs
,
state
);
}
/* Do post notifications when there are chances that transition has failed */
static
void
cpufreq_notify_post_transition
(
struct
cpufreq_policy
*
policy
,
struct
cpufreq_freqs
*
freqs
,
int
transition_failed
)
...
...
drivers/cpufreq/intel_pstate.c
浏览文件 @
96607113
...
...
@@ -1939,13 +1939,51 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
return
0
;
}
/* Use of trace in passive mode:
*
* In passive mode the trace core_busy field (also known as the
* performance field, and lablelled as such on the graphs; also known as
* core_avg_perf) is not needed and so is re-assigned to indicate if the
* driver call was via the normal or fast switch path. Various graphs
* output from the intel_pstate_tracer.py utility that include core_busy
* (or performance or core_avg_perf) have a fixed y-axis from 0 to 100%,
* so we use 10 to indicate the the normal path through the driver, and
* 90 to indicate the fast switch path through the driver.
* The scaled_busy field is not used, and is set to 0.
*/
#define INTEL_PSTATE_TRACE_TARGET 10
#define INTEL_PSTATE_TRACE_FAST_SWITCH 90
static
void
intel_cpufreq_trace
(
struct
cpudata
*
cpu
,
unsigned
int
trace_type
,
int
old_pstate
)
{
struct
sample
*
sample
;
if
(
!
trace_pstate_sample_enabled
())
return
;
if
(
!
intel_pstate_sample
(
cpu
,
ktime_get
()))
return
;
sample
=
&
cpu
->
sample
;
trace_pstate_sample
(
trace_type
,
0
,
old_pstate
,
cpu
->
pstate
.
current_pstate
,
sample
->
mperf
,
sample
->
aperf
,
sample
->
tsc
,
get_avg_frequency
(
cpu
),
fp_toint
(
cpu
->
iowait_boost
*
100
));
}
static
int
intel_cpufreq_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
)
{
struct
cpudata
*
cpu
=
all_cpu_data
[
policy
->
cpu
];
struct
cpufreq_freqs
freqs
;
int
target_pstate
;
int
target_pstate
,
old_pstate
;
update_turbo_state
();
...
...
@@ -1965,12 +2003,14 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
break
;
}
target_pstate
=
intel_pstate_prepare_request
(
cpu
,
target_pstate
);
old_pstate
=
cpu
->
pstate
.
current_pstate
;
if
(
target_pstate
!=
cpu
->
pstate
.
current_pstate
)
{
cpu
->
pstate
.
current_pstate
=
target_pstate
;
wrmsrl_on_cpu
(
policy
->
cpu
,
MSR_IA32_PERF_CTL
,
pstate_funcs
.
get_val
(
cpu
,
target_pstate
));
}
freqs
.
new
=
target_pstate
*
cpu
->
pstate
.
scaling
;
intel_cpufreq_trace
(
cpu
,
INTEL_PSTATE_TRACE_TARGET
,
old_pstate
);
cpufreq_freq_transition_end
(
policy
,
&
freqs
,
false
);
return
0
;
...
...
@@ -1980,13 +2020,15 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
unsigned
int
target_freq
)
{
struct
cpudata
*
cpu
=
all_cpu_data
[
policy
->
cpu
];
int
target_pstate
;
int
target_pstate
,
old_pstate
;
update_turbo_state
();
target_pstate
=
DIV_ROUND_UP
(
target_freq
,
cpu
->
pstate
.
scaling
);
target_pstate
=
intel_pstate_prepare_request
(
cpu
,
target_pstate
);
old_pstate
=
cpu
->
pstate
.
current_pstate
;
intel_pstate_update_pstate
(
cpu
,
target_pstate
);
intel_cpufreq_trace
(
cpu
,
INTEL_PSTATE_TRACE_FAST_SWITCH
,
old_pstate
);
return
target_pstate
*
cpu
->
pstate
.
scaling
;
}
...
...
drivers/cpufreq/s3c2440-cpufreq.c
浏览文件 @
96607113
...
...
@@ -143,7 +143,7 @@ static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
{
unsigned
long
clkdiv
,
camdiv
;
s3c_freq_dbg
(
"%s: div
si
ors: h=%d, p=%d
\n
"
,
__func__
,
s3c_freq_dbg
(
"%s: div
is
ors: h=%d, p=%d
\n
"
,
__func__
,
cfg
->
divs
.
h_divisor
,
cfg
->
divs
.
p_divisor
);
clkdiv
=
__raw_readl
(
S3C2410_CLKDIVN
);
...
...
drivers/cpufreq/speedstep-lib.c
浏览文件 @
96607113
...
...
@@ -252,7 +252,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency);
*********************************************************************/
/* Keep in sync with the x86_cpu_id tables in the different modules */
unsigned
int
speedstep_detect_processor
(
void
)
enum
speedstep_processor
speedstep_detect_processor
(
void
)
{
struct
cpuinfo_x86
*
c
=
&
cpu_data
(
0
);
u32
ebx
,
msr_lo
,
msr_hi
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录