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
42807537
Commit
42807537
authored
Dec 11, 2020
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back cpufreq material for v5.11.
parents
05b8955f
bb025fb6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
91 deletions
+87
-91
drivers/cpufreq/cppc_cpufreq.c
drivers/cpufreq/cppc_cpufreq.c
+82
-81
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+5
-5
include/linux/cpufreq.h
include/linux/cpufreq.h
+0
-5
No files found.
drivers/cpufreq/cppc_cpufreq.c
View file @
42807537
...
...
@@ -26,8 +26,8 @@
/* Minimum struct length needed for the DMI processor entry we want */
#define DMI_ENTRY_PROCESSOR_MIN_LENGTH 48
/* Off
es
t in the DMI processor structure for the max frequency */
#define DMI_PROCESSOR_MAX_SPEED
0x14
/* Off
se
t in the DMI processor structure for the max frequency */
#define DMI_PROCESSOR_MAX_SPEED
0x14
/*
* These structs contain information parsed from per CPU
...
...
@@ -96,11 +96,11 @@ static u64 cppc_get_dmi_max_khz(void)
* and extrapolate the rest
* For perf/freq > Nominal, we use the ratio perf:freq at Nominal for conversion
*/
static
unsigned
int
cppc_cpufreq_perf_to_khz
(
struct
cppc_cpudata
*
cpu
,
unsigned
int
perf
)
static
unsigned
int
cppc_cpufreq_perf_to_khz
(
struct
cppc_cpudata
*
cpu
_data
,
unsigned
int
perf
)
{
struct
cppc_perf_caps
*
caps
=
&
cpu_data
->
perf_caps
;
static
u64
max_khz
;
struct
cppc_perf_caps
*
caps
=
&
cpu
->
perf_caps
;
u64
mul
,
div
;
if
(
caps
->
lowest_freq
&&
caps
->
nominal_freq
)
{
...
...
@@ -120,11 +120,11 @@ static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu,
return
(
u64
)
perf
*
mul
/
div
;
}
static
unsigned
int
cppc_cpufreq_khz_to_perf
(
struct
cppc_cpudata
*
cpu
,
unsigned
int
freq
)
static
unsigned
int
cppc_cpufreq_khz_to_perf
(
struct
cppc_cpudata
*
cpu
_data
,
unsigned
int
freq
)
{
struct
cppc_perf_caps
*
caps
=
&
cpu_data
->
perf_caps
;
static
u64
max_khz
;
struct
cppc_perf_caps
*
caps
=
&
cpu
->
perf_caps
;
u64
mul
,
div
;
if
(
caps
->
lowest_freq
&&
caps
->
nominal_freq
)
{
...
...
@@ -146,32 +146,30 @@ static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu,
}
static
int
cppc_cpufreq_set_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
)
unsigned
int
target_freq
,
unsigned
int
relation
)
{
struct
cppc_cpudata
*
cpu
;
struct
cppc_cpudata
*
cpu
_data
=
all_cpu_data
[
policy
->
cpu
]
;
struct
cpufreq_freqs
freqs
;
u32
desired_perf
;
int
ret
=
0
;
cpu
=
all_cpu_data
[
policy
->
cpu
];
desired_perf
=
cppc_cpufreq_khz_to_perf
(
cpu
,
target_freq
);
desired_perf
=
cppc_cpufreq_khz_to_perf
(
cpu_data
,
target_freq
);
/* Return if it is exactly the same perf */
if
(
desired_perf
==
cpu
->
perf_ctrls
.
desired_perf
)
if
(
desired_perf
==
cpu
_data
->
perf_ctrls
.
desired_perf
)
return
ret
;
cpu
->
perf_ctrls
.
desired_perf
=
desired_perf
;
cpu
_data
->
perf_ctrls
.
desired_perf
=
desired_perf
;
freqs
.
old
=
policy
->
cur
;
freqs
.
new
=
target_freq
;
cpufreq_freq_transition_begin
(
policy
,
&
freqs
);
ret
=
cppc_set_perf
(
cpu
->
cpu
,
&
cpu
->
perf_ctrls
);
ret
=
cppc_set_perf
(
cpu
_data
->
cpu
,
&
cpu_data
->
perf_ctrls
);
cpufreq_freq_transition_end
(
policy
,
&
freqs
,
ret
!=
0
);
if
(
ret
)
pr_debug
(
"Failed to set target on CPU:%d. ret:%d
\n
"
,
cpu
->
cpu
,
ret
);
cpu_data
->
cpu
,
ret
);
return
ret
;
}
...
...
@@ -184,28 +182,29 @@ static int cppc_verify_policy(struct cpufreq_policy_data *policy)
static
void
cppc_cpufreq_stop_cpu
(
struct
cpufreq_policy
*
policy
)
{
int
cpu_num
=
policy
->
cpu
;
struct
cppc_cpudata
*
cpu
=
all_cpu_data
[
cpu_num
];
struct
cppc_cpudata
*
cpu_data
=
all_cpu_data
[
policy
->
cpu
];
struct
cppc_perf_caps
*
caps
=
&
cpu_data
->
perf_caps
;
unsigned
int
cpu
=
policy
->
cpu
;
int
ret
;
cpu
->
perf_ctrls
.
desired_perf
=
cpu
->
perf_caps
.
lowest_perf
;
cpu
_data
->
perf_ctrls
.
desired_perf
=
caps
->
lowest_perf
;
ret
=
cppc_set_perf
(
cpu
_num
,
&
cpu
->
perf_ctrls
);
ret
=
cppc_set_perf
(
cpu
,
&
cpu_data
->
perf_ctrls
);
if
(
ret
)
pr_debug
(
"Err setting perf value:%d on CPU:%d. ret:%d
\n
"
,
cpu
->
perf_caps
.
lowest_perf
,
cpu_num
,
ret
);
caps
->
lowest_perf
,
cpu
,
ret
);
}
/*
* The PCC subspace describes the rate at which platform can accept commands
* on the shared PCC channel (including READs which do not count towards freq
* trasition requests), so ideally we need to use the PCC values as a fallback
* tra
n
sition requests), so ideally we need to use the PCC values as a fallback
* if we don't have a platform specific transition_delay_us
*/
#ifdef CONFIG_ARM64
#include <asm/cputype.h>
static
unsigned
int
cppc_cpufreq_get_transition_delay_us
(
int
cpu
)
static
unsigned
int
cppc_cpufreq_get_transition_delay_us
(
unsigned
int
cpu
)
{
unsigned
long
implementor
=
read_cpuid_implementor
();
unsigned
long
part_num
=
read_cpuid_part_number
();
...
...
@@ -233,7 +232,7 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
#else
static
unsigned
int
cppc_cpufreq_get_transition_delay_us
(
int
cpu
)
static
unsigned
int
cppc_cpufreq_get_transition_delay_us
(
unsigned
int
cpu
)
{
return
cppc_get_transition_latency
(
cpu
)
/
NSEC_PER_USEC
;
}
...
...
@@ -241,54 +240,57 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(int cpu)
static
int
cppc_cpufreq_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
struct
cppc_cpudata
*
cpu
;
unsigned
int
cpu_num
=
policy
->
cpu
;
struct
cppc_cpudata
*
cpu_data
=
all_cpu_data
[
policy
->
cpu
];
struct
cppc_perf_caps
*
caps
=
&
cpu_data
->
perf_caps
;
unsigned
int
cpu
=
policy
->
cpu
;
int
ret
=
0
;
cpu
=
all_cpu_data
[
policy
->
cpu
];
cpu
->
cpu
=
cpu_num
;
ret
=
cppc_get_perf_caps
(
policy
->
cpu
,
&
cpu
->
perf_caps
);
cpu_data
->
cpu
=
cpu
;
ret
=
cppc_get_perf_caps
(
cpu
,
caps
);
if
(
ret
)
{
pr_debug
(
"Err reading CPU%d perf capabilities. ret:%d
\n
"
,
cpu_num
,
ret
);
cpu
,
ret
);
return
ret
;
}
/* Convert the lowest and nominal freq from MHz to KHz */
c
pu
->
perf_caps
.
lowest_freq
*=
1000
;
c
pu
->
perf_caps
.
nominal_freq
*=
1000
;
c
aps
->
lowest_freq
*=
1000
;
c
aps
->
nominal_freq
*=
1000
;
/*
* Set min to lowest nonlinear perf to avoid any efficiency penalty (see
* Section 8.4.7.1.1.5 of ACPI 6.1 spec)
*/
policy
->
min
=
cppc_cpufreq_perf_to_khz
(
cpu
,
cpu
->
perf_caps
.
lowest_nonlinear_perf
);
policy
->
max
=
cppc_cpufreq_perf_to_khz
(
cpu
,
cpu
->
perf_caps
.
nominal_perf
);
policy
->
min
=
cppc_cpufreq_perf_to_khz
(
cpu_data
,
caps
->
lowest_nonlinear_perf
);
policy
->
max
=
cppc_cpufreq_perf_to_khz
(
cpu_data
,
caps
->
nominal_perf
);
/*
* Set cpuinfo.min_freq to Lowest to make the full range of performance
* available if userspace wants to use any perf between lowest & lowest
* nonlinear perf
*/
policy
->
cpuinfo
.
min_freq
=
cppc_cpufreq_perf_to_khz
(
cpu
,
cpu
->
perf_caps
.
lowest_perf
);
policy
->
cpuinfo
.
max_freq
=
cppc_cpufreq_perf_to_khz
(
cpu
,
cpu
->
perf_caps
.
nominal_perf
);
policy
->
cpuinfo
.
min_freq
=
cppc_cpufreq_perf_to_khz
(
cpu_data
,
caps
->
lowest_perf
);
policy
->
cpuinfo
.
max_freq
=
cppc_cpufreq_perf_to_khz
(
cpu_data
,
caps
->
nominal_perf
);
policy
->
transition_delay_us
=
cppc_cpufreq_get_transition_delay_us
(
cpu
_num
);
policy
->
shared_type
=
cpu
->
shared_type
;
policy
->
transition_delay_us
=
cppc_cpufreq_get_transition_delay_us
(
cpu
);
policy
->
shared_type
=
cpu
_data
->
shared_type
;
if
(
policy
->
shared_type
==
CPUFREQ_SHARED_TYPE_ANY
)
{
int
i
;
cpumask_copy
(
policy
->
cpus
,
cpu
->
shared_cpu_map
);
cpumask_copy
(
policy
->
cpus
,
cpu
_data
->
shared_cpu_map
);
for_each_cpu
(
i
,
policy
->
cpus
)
{
if
(
unlikely
(
i
==
policy
->
cpu
))
if
(
unlikely
(
i
==
cpu
))
continue
;
memcpy
(
&
all_cpu_data
[
i
]
->
perf_caps
,
&
cpu
->
perf_
caps
,
sizeof
(
cpu
->
perf_caps
));
memcpy
(
&
all_cpu_data
[
i
]
->
perf_caps
,
caps
,
sizeof
(
cpu
_data
->
perf_caps
));
}
}
else
if
(
policy
->
shared_type
==
CPUFREQ_SHARED_TYPE_ALL
)
{
/* Support only SW_ANY for now. */
...
...
@@ -296,24 +298,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy)
return
-
EFAULT
;
}
cpu
->
cur_policy
=
policy
;
cpu
_data
->
cur_policy
=
policy
;
/*
* If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost
* is supported.
*/
if
(
c
pu
->
perf_caps
.
highest_perf
>
cpu
->
perf_caps
.
nominal_perf
)
if
(
c
aps
->
highest_perf
>
caps
->
nominal_perf
)
boost_supported
=
true
;
/* Set policy->cur to max now. The governors will adjust later. */
policy
->
cur
=
cppc_cpufreq_perf_to_khz
(
cpu
,
cpu
->
perf_caps
.
highest_perf
);
cpu
->
perf_ctrls
.
desired_perf
=
cpu
->
perf_caps
.
highest_perf
;
policy
->
cur
=
cppc_cpufreq_perf_to_khz
(
cpu_data
,
caps
->
highest_perf
);
cpu_data
->
perf_ctrls
.
desired_perf
=
caps
->
highest_perf
;
ret
=
cppc_set_perf
(
cpu
_num
,
&
cpu
->
perf_ctrls
);
ret
=
cppc_set_perf
(
cpu
,
&
cpu_data
->
perf_ctrls
);
if
(
ret
)
pr_debug
(
"Err setting perf value:%d on CPU:%d. ret:%d
\n
"
,
cpu
->
perf_caps
.
highest_perf
,
cpu_num
,
ret
);
caps
->
highest_perf
,
cpu
,
ret
);
return
ret
;
}
...
...
@@ -326,7 +327,7 @@ static inline u64 get_delta(u64 t1, u64 t0)
return
(
u32
)
t1
-
(
u32
)
t0
;
}
static
int
cppc_get_rate_from_fbctrs
(
struct
cppc_cpudata
*
cpu
,
static
int
cppc_get_rate_from_fbctrs
(
struct
cppc_cpudata
*
cpu
_data
,
struct
cppc_perf_fb_ctrs
fb_ctrs_t0
,
struct
cppc_perf_fb_ctrs
fb_ctrs_t1
)
{
...
...
@@ -345,33 +346,34 @@ static int cppc_get_rate_from_fbctrs(struct cppc_cpudata *cpu,
delivered_perf
=
(
reference_perf
*
delta_delivered
)
/
delta_reference
;
else
delivered_perf
=
cpu
->
perf_ctrls
.
desired_perf
;
delivered_perf
=
cpu
_data
->
perf_ctrls
.
desired_perf
;
return
cppc_cpufreq_perf_to_khz
(
cpu
,
delivered_perf
);
return
cppc_cpufreq_perf_to_khz
(
cpu
_data
,
delivered_perf
);
}
static
unsigned
int
cppc_cpufreq_get_rate
(
unsigned
int
cpu
num
)
static
unsigned
int
cppc_cpufreq_get_rate
(
unsigned
int
cpu
)
{
struct
cppc_perf_fb_ctrs
fb_ctrs_t0
=
{
0
},
fb_ctrs_t1
=
{
0
};
struct
cppc_cpudata
*
cpu
=
all_cpu_data
[
cpunum
];
struct
cppc_cpudata
*
cpu
_data
=
all_cpu_data
[
cpu
];
int
ret
;
ret
=
cppc_get_perf_ctrs
(
cpu
num
,
&
fb_ctrs_t0
);
ret
=
cppc_get_perf_ctrs
(
cpu
,
&
fb_ctrs_t0
);
if
(
ret
)
return
ret
;
udelay
(
2
);
/* 2usec delay between sampling */
ret
=
cppc_get_perf_ctrs
(
cpu
num
,
&
fb_ctrs_t1
);
ret
=
cppc_get_perf_ctrs
(
cpu
,
&
fb_ctrs_t1
);
if
(
ret
)
return
ret
;
return
cppc_get_rate_from_fbctrs
(
cpu
,
fb_ctrs_t0
,
fb_ctrs_t1
);
return
cppc_get_rate_from_fbctrs
(
cpu
_data
,
fb_ctrs_t0
,
fb_ctrs_t1
);
}
static
int
cppc_cpufreq_set_boost
(
struct
cpufreq_policy
*
policy
,
int
state
)
{
struct
cppc_cpudata
*
cpudata
;
struct
cppc_cpudata
*
cpu_data
=
all_cpu_data
[
policy
->
cpu
];
struct
cppc_perf_caps
*
caps
=
&
cpu_data
->
perf_caps
;
int
ret
;
if
(
!
boost_supported
)
{
...
...
@@ -379,13 +381,12 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
return
-
EINVAL
;
}
cpudata
=
all_cpu_data
[
policy
->
cpu
];
if
(
state
)
policy
->
max
=
cppc_cpufreq_perf_to_khz
(
cpudata
,
cpudata
->
perf_caps
.
highest_perf
);
policy
->
max
=
cppc_cpufreq_perf_to_khz
(
cpu
_
data
,
caps
->
highest_perf
);
else
policy
->
max
=
cppc_cpufreq_perf_to_khz
(
cpudata
,
cpudata
->
perf_caps
.
nominal_perf
);
policy
->
max
=
cppc_cpufreq_perf_to_khz
(
cpu
_
data
,
caps
->
nominal_perf
);
policy
->
cpuinfo
.
max_freq
=
policy
->
max
;
ret
=
freq_qos_update_request
(
policy
->
max_freq_req
,
policy
->
max
);
...
...
@@ -412,17 +413,17 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
* platform specific mechanism. We reuse the desired performance register to
* store the real performance calculated by the platform.
*/
static
unsigned
int
hisi_cppc_cpufreq_get_rate
(
unsigned
int
cpu
num
)
static
unsigned
int
hisi_cppc_cpufreq_get_rate
(
unsigned
int
cpu
)
{
struct
cppc_cpudata
*
cpu
data
=
all_cpu_data
[
cpunum
];
struct
cppc_cpudata
*
cpu
_data
=
all_cpu_data
[
cpu
];
u64
desired_perf
;
int
ret
;
ret
=
cppc_get_desired_perf
(
cpu
num
,
&
desired_perf
);
ret
=
cppc_get_desired_perf
(
cpu
,
&
desired_perf
);
if
(
ret
<
0
)
return
-
EIO
;
return
cppc_cpufreq_perf_to_khz
(
cpudata
,
desired_perf
);
return
cppc_cpufreq_perf_to_khz
(
cpu
_
data
,
desired_perf
);
}
static
void
cppc_check_hisi_workaround
(
void
)
...
...
@@ -450,8 +451,8 @@ static void cppc_check_hisi_workaround(void)
static
int
__init
cppc_cpufreq_init
(
void
)
{
struct
cppc_cpudata
*
cpu_data
;
int
i
,
ret
=
0
;
struct
cppc_cpudata
*
cpu
;
if
(
acpi_disabled
)
return
-
ENODEV
;
...
...
@@ -466,8 +467,8 @@ static int __init cppc_cpufreq_init(void)
if
(
!
all_cpu_data
[
i
])
goto
out
;
cpu
=
all_cpu_data
[
i
];
if
(
!
zalloc_cpumask_var
(
&
cpu
->
shared_cpu_map
,
GFP_KERNEL
))
cpu
_data
=
all_cpu_data
[
i
];
if
(
!
zalloc_cpumask_var
(
&
cpu
_data
->
shared_cpu_map
,
GFP_KERNEL
))
goto
out
;
}
...
...
@@ -487,11 +488,11 @@ static int __init cppc_cpufreq_init(void)
out:
for_each_possible_cpu
(
i
)
{
cpu
=
all_cpu_data
[
i
];
if
(
!
cpu
)
cpu
_data
=
all_cpu_data
[
i
];
if
(
!
cpu
_data
)
break
;
free_cpumask_var
(
cpu
->
shared_cpu_map
);
kfree
(
cpu
);
free_cpumask_var
(
cpu
_data
->
shared_cpu_map
);
kfree
(
cpu
_data
);
}
kfree
(
all_cpu_data
);
...
...
@@ -500,15 +501,15 @@ static int __init cppc_cpufreq_init(void)
static
void
__exit
cppc_cpufreq_exit
(
void
)
{
struct
cppc_cpudata
*
cpu
;
struct
cppc_cpudata
*
cpu
_data
;
int
i
;
cpufreq_unregister_driver
(
&
cppc_cpufreq_driver
);
for_each_possible_cpu
(
i
)
{
cpu
=
all_cpu_data
[
i
];
free_cpumask_var
(
cpu
->
shared_cpu_map
);
kfree
(
cpu
);
cpu
_data
=
all_cpu_data
[
i
];
free_cpumask_var
(
cpu
_data
->
shared_cpu_map
);
kfree
(
cpu
_data
);
}
kfree
(
all_cpu_data
);
...
...
drivers/cpufreq/cpufreq.c
View file @
42807537
...
...
@@ -2123,7 +2123,7 @@ static int __target_intermediate(struct cpufreq_policy *policy,
static
int
__target_index
(
struct
cpufreq_policy
*
policy
,
int
index
)
{
struct
cpufreq_freqs
freqs
=
{.
old
=
policy
->
cur
,
.
flags
=
0
};
unsigned
int
intermediate_freq
=
0
;
unsigned
int
restore_freq
,
intermediate_freq
=
0
;
unsigned
int
newfreq
=
policy
->
freq_table
[
index
].
frequency
;
int
retval
=
-
EINVAL
;
bool
notify
;
...
...
@@ -2131,6 +2131,9 @@ static int __target_index(struct cpufreq_policy *policy, int index)
if
(
newfreq
==
policy
->
cur
)
return
0
;
/* Save last value to restore later on errors */
restore_freq
=
policy
->
cur
;
notify
=
!
(
cpufreq_driver
->
flags
&
CPUFREQ_ASYNC_NOTIFICATION
);
if
(
notify
)
{
/* Handle switching to intermediate frequency */
...
...
@@ -2168,7 +2171,7 @@ static int __target_index(struct cpufreq_policy *policy, int index)
*/
if
(
unlikely
(
retval
&&
intermediate_freq
))
{
freqs
.
old
=
intermediate_freq
;
freqs
.
new
=
policy
->
restore_freq
;
freqs
.
new
=
restore_freq
;
cpufreq_freq_transition_begin
(
policy
,
&
freqs
);
cpufreq_freq_transition_end
(
policy
,
&
freqs
,
0
);
}
...
...
@@ -2203,9 +2206,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
!
(
cpufreq_driver
->
flags
&
CPUFREQ_NEED_UPDATE_LIMITS
))
return
0
;
/* Save last value to restore later on errors */
policy
->
restore_freq
=
policy
->
cur
;
if
(
cpufreq_driver
->
target
)
return
cpufreq_driver
->
target
(
policy
,
target_freq
,
relation
);
...
...
include/linux/cpufreq.h
View file @
42807537
...
...
@@ -65,7 +65,6 @@ struct cpufreq_policy {
unsigned
int
max
;
/* in kHz */
unsigned
int
cur
;
/* in kHz, only needed if cpufreq
* governors are used */
unsigned
int
restore_freq
;
/* = policy->cur before transition */
unsigned
int
suspend_freq
;
/* freq to set during suspend */
unsigned
int
policy
;
/* see above */
...
...
@@ -314,10 +313,6 @@ struct cpufreq_driver {
/* define one out of two */
int
(
*
setpolicy
)(
struct
cpufreq_policy
*
policy
);
/*
* On failure, should always restore frequency to policy->restore_freq
* (i.e. old freq).
*/
int
(
*
target
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
);
/* Deprecated */
...
...
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