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
96607113
Commit
96607113
authored
May 18, 2018
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back cpufreq material for v4.18.
parents
0cf442c6
144ec880
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
178 additions
and
52 deletions
+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
No files found.
drivers/cpufreq/armada-37xx-cpufreq.c
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
View file @
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
;
...
...
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