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
38fc7839
Commit
38fc7839
authored
Apr 10, 2015
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back earlier cpufreq material for v4.1.
parents
e5e02de0
5acb972f
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
206 additions
and
73 deletions
+206
-73
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig
+8
-0
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Kconfig.arm
+9
-0
drivers/cpufreq/Kconfig.powerpc
drivers/cpufreq/Kconfig.powerpc
+0
-9
drivers/cpufreq/Makefile
drivers/cpufreq/Makefile
+2
-1
drivers/cpufreq/hisi-acpu-cpufreq.c
drivers/cpufreq/hisi-acpu-cpufreq.c
+42
-0
drivers/cpufreq/powernv-cpufreq.c
drivers/cpufreq/powernv-cpufreq.c
+46
-1
drivers/cpufreq/qoriq-cpufreq.c
drivers/cpufreq/qoriq-cpufreq.c
+99
-62
No files found.
drivers/cpufreq/Kconfig
View file @
38fc7839
...
...
@@ -293,5 +293,13 @@ config SH_CPU_FREQ
If unsure, say N.
endif
config QORIQ_CPUFREQ
tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
depends on OF && COMMON_CLK && (PPC_E500MC || ARM)
select CLK_QORIQ
help
This adds the CPUFreq driver support for Freescale QorIQ SoCs
which are capable of changing the CPU's frequency dynamically.
endif
endmenu
drivers/cpufreq/Kconfig.arm
View file @
38fc7839
...
...
@@ -108,6 +108,15 @@ config ARM_HIGHBANK_CPUFREQ
If in doubt, say N.
config ARM_HISI_ACPU_CPUFREQ
tristate "Hisilicon ACPU CPUfreq driver"
depends on ARCH_HISI && CPUFREQ_DT
select PM_OPP
help
This enables the hisilicon ACPU CPUfreq driver.
If in doubt, say N.
config ARM_IMX6Q_CPUFREQ
tristate "Freescale i.MX6 cpufreq support"
depends on ARCH_MXC
...
...
drivers/cpufreq/Kconfig.powerpc
View file @
38fc7839
...
...
@@ -23,15 +23,6 @@ config CPU_FREQ_MAPLE
This adds support for frequency switching on Maple 970FX
Evaluation Board and compatible boards (IBM JS2x blades).
config PPC_CORENET_CPUFREQ
tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
depends on PPC_E500MC && OF && COMMON_CLK
select CLK_QORIQ
help
This adds the CPUFreq driver support for Freescale e500mc,
e5500 and e6500 series SoCs which are capable of changing
the CPU's frequency dynamically.
config CPU_FREQ_PMAC
bool "Support for Apple PowerBooks"
depends on ADB_PMU && PPC32
...
...
drivers/cpufreq/Makefile
View file @
38fc7839
...
...
@@ -59,6 +59,7 @@ arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS5250_CPUFREQ)
+=
exynos5250-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)
+=
exynos5440-cpufreq.o
obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)
+=
highbank-cpufreq.o
obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ)
+=
hisi-acpu-cpufreq.o
obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)
+=
imx6q-cpufreq.o
obj-$(CONFIG_ARM_INTEGRATOR)
+=
integrator-cpufreq.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)
+=
kirkwood-cpufreq.o
...
...
@@ -85,7 +86,7 @@ obj-$(CONFIG_CPU_FREQ_CBE) += ppc-cbe-cpufreq.o
ppc-cbe-cpufreq-y
+=
ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
obj-$(CONFIG_CPU_FREQ_CBE_PMI)
+=
ppc_cbe_cpufreq_pmi.o
obj-$(CONFIG_CPU_FREQ_MAPLE)
+=
maple-cpufreq.o
obj-$(CONFIG_
PPC_CORENET_CPUFREQ)
+=
ppc-corenet
-cpufreq.o
obj-$(CONFIG_
QORIQ_CPUFREQ)
+=
qoriq
-cpufreq.o
obj-$(CONFIG_CPU_FREQ_PMAC)
+=
pmac32-cpufreq.o
obj-$(CONFIG_CPU_FREQ_PMAC64)
+=
pmac64-cpufreq.o
obj-$(CONFIG_PPC_PASEMI_CPUFREQ)
+=
pasemi-cpufreq.o
...
...
drivers/cpufreq/hisi-acpu-cpufreq.c
0 → 100644
View file @
38fc7839
/*
* Hisilicon Platforms Using ACPU CPUFreq Support
*
* Copyright (c) 2015 Hisilicon Limited.
* Copyright (c) 2015 Linaro Limited.
*
* Leo Yan <leo.yan@linaro.org>
*
* 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.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
static
int
__init
hisi_acpu_cpufreq_driver_init
(
void
)
{
struct
platform_device
*
pdev
;
if
(
!
of_machine_is_compatible
(
"hisilicon,hi6220"
))
return
-
ENODEV
;
pdev
=
platform_device_register_simple
(
"cpufreq-dt"
,
-
1
,
NULL
,
0
);
return
PTR_ERR_OR_ZERO
(
pdev
);
}
module_init
(
hisi_acpu_cpufreq_driver_init
);
MODULE_AUTHOR
(
"Leo Yan <leo.yan@linaro.org>"
);
MODULE_DESCRIPTION
(
"Hisilicon acpu cpufreq driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/cpufreq/powernv-cpufreq.c
View file @
38fc7839
...
...
@@ -34,9 +34,13 @@
#include <asm/smp.h>
/* Required for cpu_sibling_mask() in UP configs */
#define POWERNV_MAX_PSTATES 256
#define PMSR_PSAFE_ENABLE (1UL << 30)
#define PMSR_SPR_EM_DISABLE (1UL << 31)
#define PMSR_MAX(x) ((x >> 32) & 0xFF)
#define PMSR_LP(x) ((x >> 48) & 0xFF)
static
struct
cpufreq_frequency_table
powernv_freqs
[
POWERNV_MAX_PSTATES
+
1
];
static
bool
rebooting
;
static
bool
rebooting
,
throttled
;
/*
* Note: The set of pstates consists of contiguous integers, the
...
...
@@ -294,6 +298,44 @@ static inline unsigned int get_nominal_index(void)
return
powernv_pstate_info
.
max
-
powernv_pstate_info
.
nominal
;
}
static
void
powernv_cpufreq_throttle_check
(
unsigned
int
cpu
)
{
unsigned
long
pmsr
;
int
pmsr_pmax
,
pmsr_lp
;
pmsr
=
get_pmspr
(
SPRN_PMSR
);
/* Check for Pmax Capping */
pmsr_pmax
=
(
s8
)
PMSR_MAX
(
pmsr
);
if
(
pmsr_pmax
!=
powernv_pstate_info
.
max
)
{
throttled
=
true
;
pr_info
(
"CPU %d Pmax is reduced to %d
\n
"
,
cpu
,
pmsr_pmax
);
pr_info
(
"Max allowed Pstate is capped
\n
"
);
}
/*
* Check for Psafe by reading LocalPstate
* or check if Psafe_mode_active is set in PMSR.
*/
pmsr_lp
=
(
s8
)
PMSR_LP
(
pmsr
);
if
((
pmsr_lp
<
powernv_pstate_info
.
min
)
||
(
pmsr
&
PMSR_PSAFE_ENABLE
))
{
throttled
=
true
;
pr_info
(
"Pstate set to safe frequency
\n
"
);
}
/* Check if SPR_EM_DISABLE is set in PMSR */
if
(
pmsr
&
PMSR_SPR_EM_DISABLE
)
{
throttled
=
true
;
pr_info
(
"Frequency Control disabled from OS
\n
"
);
}
if
(
throttled
)
{
pr_info
(
"PMSR = %16lx
\n
"
,
pmsr
);
pr_crit
(
"CPU Frequency could be throttled
\n
"
);
}
}
/*
* powernv_cpufreq_target_index: Sets the frequency corresponding to
* the cpufreq table entry indexed by new_index on the cpus in the
...
...
@@ -307,6 +349,9 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
if
(
unlikely
(
rebooting
)
&&
new_index
!=
get_nominal_index
())
return
0
;
if
(
!
throttled
)
powernv_cpufreq_throttle_check
(
smp_processor_id
());
freq_data
.
pstate_id
=
powernv_freqs
[
new_index
].
driver_data
;
/*
...
...
drivers/cpufreq/
ppc-corenet
-cpufreq.c
→
drivers/cpufreq/
qoriq
-cpufreq.c
View file @
38fc7839
/*
* Copyright 2013 Freescale Semiconductor, Inc.
*
* CPU Frequency Scaling driver for Freescale
PowerPC corenet
SoCs.
* CPU Frequency Scaling driver for Freescale
QorIQ
SoCs.
*
* 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
...
...
@@ -20,12 +20,11 @@
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <sysdev/fsl_soc.h>
#include <asm/smp.h>
/* for get_hard_smp_processor_id() in UP configs */
/**
* struct cpu_data
- per CPU data struct
* struct cpu_data
* @parent: the parent node of cpu clock
* @table: frequency table
*/
...
...
@@ -69,17 +68,78 @@ static const struct soc_data sdata[] = {
static
u32
min_cpufreq
;
static
const
u32
*
fmask
;
static
DEFINE_PER_CPU
(
struct
cpu_data
*
,
cpu_data
);
#if defined(CONFIG_ARM)
static
int
get_cpu_physical_id
(
int
cpu
)
{
return
topology_core_id
(
cpu
);
}
#else
static
int
get_cpu_physical_id
(
int
cpu
)
{
return
get_hard_smp_processor_id
(
cpu
);
}
#endif
/* cpumask in a cluster */
static
DEFINE_PER_CPU
(
cpumask_var_t
,
cpu_mask
);
static
u32
get_bus_freq
(
void
)
{
struct
device_node
*
soc
;
u32
sysfreq
;
#ifndef CONFIG_SMP
static
inline
const
struct
cpumask
*
cpu_core_mask
(
int
cpu
)
soc
=
of_find_node_by_type
(
NULL
,
"soc"
);
if
(
!
soc
)
return
0
;
if
(
of_property_read_u32
(
soc
,
"bus-frequency"
,
&
sysfreq
))
sysfreq
=
0
;
of_node_put
(
soc
);
return
sysfreq
;
}
static
struct
device_node
*
cpu_to_clk_node
(
int
cpu
)
{
return
cpumask_of
(
0
);
struct
device_node
*
np
,
*
clk_np
;
if
(
!
cpu_present
(
cpu
))
return
NULL
;
np
=
of_get_cpu_node
(
cpu
,
NULL
);
if
(
!
np
)
return
NULL
;
clk_np
=
of_parse_phandle
(
np
,
"clocks"
,
0
);
if
(
!
clk_np
)
return
NULL
;
of_node_put
(
np
);
return
clk_np
;
}
/* traverse cpu nodes to get cpu mask of sharing clock wire */
static
void
set_affected_cpus
(
struct
cpufreq_policy
*
policy
)
{
struct
device_node
*
np
,
*
clk_np
;
struct
cpumask
*
dstp
=
policy
->
cpus
;
int
i
;
np
=
cpu_to_clk_node
(
policy
->
cpu
);
if
(
!
np
)
return
;
for_each_present_cpu
(
i
)
{
clk_np
=
cpu_to_clk_node
(
i
);
if
(
!
clk_np
)
continue
;
if
(
clk_np
==
np
)
cpumask_set_cpu
(
i
,
dstp
);
of_node_put
(
clk_np
);
}
of_node_put
(
np
);
}
#endif
/* reduce the duplicated frequencies in frequency table */
static
void
freq_table_redup
(
struct
cpufreq_frequency_table
*
freq_table
,
...
...
@@ -107,6 +167,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
int
i
,
j
,
ind
;
unsigned
int
freq
,
max_freq
;
struct
cpufreq_frequency_table
table
;
for
(
i
=
0
;
i
<
count
-
1
;
i
++
)
{
max_freq
=
freq_table
[
i
].
frequency
;
ind
=
i
;
...
...
@@ -131,7 +192,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
}
}
static
int
corenet
_cpufreq_cpu_init
(
struct
cpufreq_policy
*
policy
)
static
int
qoriq
_cpufreq_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
struct
device_node
*
np
;
int
i
,
count
,
ret
;
...
...
@@ -147,10 +208,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
return
-
ENODEV
;
data
=
kzalloc
(
sizeof
(
*
data
),
GFP_KERNEL
);
if
(
!
data
)
{
pr_err
(
"%s: no memory
\n
"
,
__func__
);
if
(
!
data
)
goto
err_np
;
}
policy
->
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
policy
->
clk
))
{
...
...
@@ -172,7 +231,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
}
if
(
fmask
)
mask
=
fmask
[
get_
hard_smp_processor
_id
(
cpu
)];
mask
=
fmask
[
get_
cpu_physical
_id
(
cpu
)];
else
mask
=
0x0
;
...
...
@@ -203,13 +262,12 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
data
->
table
=
table
;
/* update ->cpus if we have cluster, no harm if not */
cpumask_copy
(
policy
->
cpus
,
per_cpu
(
cpu_mask
,
cpu
));
for_each_cpu
(
i
,
per_cpu
(
cpu_mask
,
cpu
))
per_cpu
(
cpu_data
,
i
)
=
data
;
set_affected_cpus
(
policy
);
policy
->
driver_data
=
data
;
/* Minimum transition latency is 12 platform clocks */
u64temp
=
12ULL
*
NSEC_PER_SEC
;
do_div
(
u64temp
,
fsl_get_sy
s_freq
());
do_div
(
u64temp
,
get_bu
s_freq
());
policy
->
cpuinfo
.
transition_latency
=
u64temp
+
1
;
of_node_put
(
np
);
...
...
@@ -221,7 +279,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
err_node:
of_node_put
(
data
->
parent
);
err_nomem2:
p
er_cpu
(
cpu_data
,
cpu
)
=
NULL
;
p
olicy
->
driver_data
=
NULL
;
kfree
(
data
);
err_np:
of_node_put
(
np
);
...
...
@@ -229,43 +287,40 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
return
-
ENODEV
;
}
static
int
__exit
corenet
_cpufreq_cpu_exit
(
struct
cpufreq_policy
*
policy
)
static
int
__exit
qoriq
_cpufreq_cpu_exit
(
struct
cpufreq_policy
*
policy
)
{
struct
cpu_data
*
data
=
per_cpu
(
cpu_data
,
policy
->
cpu
);
unsigned
int
cpu
;
struct
cpu_data
*
data
=
policy
->
driver_data
;
of_node_put
(
data
->
parent
);
kfree
(
data
->
table
);
kfree
(
data
);
for_each_cpu
(
cpu
,
per_cpu
(
cpu_mask
,
policy
->
cpu
))
per_cpu
(
cpu_data
,
cpu
)
=
NULL
;
policy
->
driver_data
=
NULL
;
return
0
;
}
static
int
corenet
_cpufreq_target
(
struct
cpufreq_policy
*
policy
,
static
int
qoriq
_cpufreq_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
index
)
{
struct
clk
*
parent
;
struct
cpu_data
*
data
=
p
er_cpu
(
cpu_data
,
policy
->
cpu
)
;
struct
cpu_data
*
data
=
p
olicy
->
driver_data
;
parent
=
of_clk_get
(
data
->
parent
,
data
->
table
[
index
].
driver_data
);
return
clk_set_parent
(
policy
->
clk
,
parent
);
}
static
struct
cpufreq_driver
ppc_corenet
_cpufreq_driver
=
{
.
name
=
"
ppc
_cpufreq"
,
static
struct
cpufreq_driver
qoriq
_cpufreq_driver
=
{
.
name
=
"
qoriq
_cpufreq"
,
.
flags
=
CPUFREQ_CONST_LOOPS
,
.
init
=
corenet
_cpufreq_cpu_init
,
.
exit
=
__exit_p
(
corenet
_cpufreq_cpu_exit
),
.
init
=
qoriq
_cpufreq_cpu_init
,
.
exit
=
__exit_p
(
qoriq
_cpufreq_cpu_exit
),
.
verify
=
cpufreq_generic_frequency_table_verify
,
.
target_index
=
corenet
_cpufreq_target
,
.
target_index
=
qoriq
_cpufreq_target
,
.
get
=
cpufreq_generic_get
,
.
attr
=
cpufreq_generic_attr
,
};
static
const
struct
of_device_id
node_matches
[]
__init
data
=
{
static
const
struct
of_device_id
node_matches
[]
__init
const
=
{
{
.
compatible
=
"fsl,p2041-clockgen"
,
.
data
=
&
sdata
[
0
],
},
{
.
compatible
=
"fsl,p3041-clockgen"
,
.
data
=
&
sdata
[
0
],
},
{
.
compatible
=
"fsl,p5020-clockgen"
,
.
data
=
&
sdata
[
1
],
},
...
...
@@ -275,61 +330,43 @@ static const struct of_device_id node_matches[] __initdata = {
{}
};
static
int
__init
ppc_corenet
_cpufreq_init
(
void
)
static
int
__init
qoriq
_cpufreq_init
(
void
)
{
int
ret
;
struct
device_node
*
np
;
const
struct
of_device_id
*
match
;
const
struct
soc_data
*
data
;
unsigned
int
cpu
;
np
=
of_find_matching_node
(
NULL
,
node_matches
);
if
(
!
np
)
return
-
ENODEV
;
for_each_possible_cpu
(
cpu
)
{
if
(
!
alloc_cpumask_var
(
&
per_cpu
(
cpu_mask
,
cpu
),
GFP_KERNEL
))
goto
err_mask
;
cpumask_copy
(
per_cpu
(
cpu_mask
,
cpu
),
cpu_core_mask
(
cpu
));
}
match
=
of_match_node
(
node_matches
,
np
);
data
=
match
->
data
;
if
(
data
)
{
if
(
data
->
flag
)
fmask
=
data
->
freq_mask
;
min_cpufreq
=
fsl_get_sy
s_freq
();
min_cpufreq
=
get_bu
s_freq
();
}
else
{
min_cpufreq
=
fsl_get_sy
s_freq
()
/
2
;
min_cpufreq
=
get_bu
s_freq
()
/
2
;
}
of_node_put
(
np
);
ret
=
cpufreq_register_driver
(
&
ppc_corenet
_cpufreq_driver
);
ret
=
cpufreq_register_driver
(
&
qoriq
_cpufreq_driver
);
if
(
!
ret
)
pr_info
(
"Freescale
PowerPC corenet
CPU frequency scaling driver
\n
"
);
pr_info
(
"Freescale
QorIQ
CPU frequency scaling driver
\n
"
);
return
ret
;
err_mask:
for_each_possible_cpu
(
cpu
)
free_cpumask_var
(
per_cpu
(
cpu_mask
,
cpu
));
return
-
ENOMEM
;
}
module_init
(
ppc_corenet
_cpufreq_init
);
module_init
(
qoriq
_cpufreq_init
);
static
void
__exit
ppc_corenet
_cpufreq_exit
(
void
)
static
void
__exit
qoriq
_cpufreq_exit
(
void
)
{
unsigned
int
cpu
;
for_each_possible_cpu
(
cpu
)
free_cpumask_var
(
per_cpu
(
cpu_mask
,
cpu
));
cpufreq_unregister_driver
(
&
ppc_corenet_cpufreq_driver
);
cpufreq_unregister_driver
(
&
qoriq_cpufreq_driver
);
}
module_exit
(
ppc_corenet
_cpufreq_exit
);
module_exit
(
qoriq
_cpufreq_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Tang Yuantian <Yuantian.Tang@freescale.com>"
);
MODULE_DESCRIPTION
(
"cpufreq driver for Freescale
e500mc
series SoCs"
);
MODULE_DESCRIPTION
(
"cpufreq driver for Freescale
QorIQ
series SoCs"
);
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