diff options
author | Gregory CLEMENT <gregory.clement@free-electrons.com> | 2014-04-14 11:10:13 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-05-08 12:19:02 -0400 |
commit | b858fbc1919720f7f54360098ece03b383e961fa (patch) | |
tree | 34616729f8b27f63ca66d7c11c9513e2179e742f | |
parent | d163ee165bd49a51f77bae632ebf37eda4899d0e (diff) |
cpuidle: mvebu: Add initial CPU idle support for Armada 370/XP SoC
Add the wfi, cpu idle and cpu deep idle power states support for the
Armada XP SoCs.
All the latencies and the power consumption values used at the
"armada_370_xp_idle_driver" structure are preliminary and will be
modified in the future after running some measurements and analysis.
Based on the work of Nadav Haklai.
Signed-off-by: Nadav Haklai <nadavh@marvell.com>
Link: https://lkml.kernel.org/r/1397488214-20685-11-git-send-email-gregory.clement@free-electrons.com
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Link: https://lkml.kernel.org/r/1397488214-20685-11-git-send-email-gregory.clement@free-electrons.com
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r-- | drivers/cpuidle/Kconfig.arm | 5 | ||||
-rw-r--r-- | drivers/cpuidle/Makefile | 1 | ||||
-rw-r--r-- | drivers/cpuidle/cpuidle-armada-370-xp.c | 93 |
3 files changed, 99 insertions, 0 deletions
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 97ccc31dbdd8..5bb94780d377 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm | |||
@@ -1,6 +1,11 @@ | |||
1 | # | 1 | # |
2 | # ARM CPU Idle drivers | 2 | # ARM CPU Idle drivers |
3 | # | 3 | # |
4 | config ARM_ARMADA_370_XP_CPUIDLE | ||
5 | bool "CPU Idle Driver for Armada 370/XP family processors" | ||
6 | depends on ARCH_MVEBU | ||
7 | help | ||
8 | Select this to enable cpuidle on Armada 370/XP processors. | ||
4 | 9 | ||
5 | config ARM_BIG_LITTLE_CPUIDLE | 10 | config ARM_BIG_LITTLE_CPUIDLE |
6 | bool "Support for ARM big.LITTLE processors" | 11 | bool "Support for ARM big.LITTLE processors" |
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index f71ae1b373c5..9902d052bd87 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o | |||
7 | 7 | ||
8 | ################################################################################## | 8 | ################################################################################## |
9 | # ARM SoC drivers | 9 | # ARM SoC drivers |
10 | obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o | ||
10 | obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o | 11 | obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o |
11 | obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o | 12 | obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o |
12 | obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o | 13 | obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o |
diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c new file mode 100644 index 000000000000..28587d0f3947 --- /dev/null +++ b/drivers/cpuidle/cpuidle-armada-370-xp.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Marvell Armada 370 and Armada XP SoC cpuidle driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Marvell | ||
5 | * | ||
6 | * Nadav Haklai <nadavh@marvell.com> | ||
7 | * Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | * | ||
13 | * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com> | ||
14 | */ | ||
15 | |||
16 | #include <linux/cpu_pm.h> | ||
17 | #include <linux/cpuidle.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/suspend.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <asm/cpuidle.h> | ||
23 | |||
24 | #define ARMADA_370_XP_MAX_STATES 3 | ||
25 | #define ARMADA_370_XP_FLAG_DEEP_IDLE 0x10000 | ||
26 | |||
27 | static int (*armada_370_xp_cpu_suspend)(int); | ||
28 | |||
29 | static int armada_370_xp_enter_idle(struct cpuidle_device *dev, | ||
30 | struct cpuidle_driver *drv, | ||
31 | int index) | ||
32 | { | ||
33 | int ret; | ||
34 | bool deepidle = false; | ||
35 | cpu_pm_enter(); | ||
36 | |||
37 | if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE) | ||
38 | deepidle = true; | ||
39 | |||
40 | ret = armada_370_xp_cpu_suspend(deepidle); | ||
41 | if (ret) | ||
42 | return ret; | ||
43 | |||
44 | cpu_pm_exit(); | ||
45 | |||
46 | return index; | ||
47 | } | ||
48 | |||
49 | static struct cpuidle_driver armada_370_xp_idle_driver = { | ||
50 | .name = "armada_370_xp_idle", | ||
51 | .states[0] = ARM_CPUIDLE_WFI_STATE, | ||
52 | .states[1] = { | ||
53 | .enter = armada_370_xp_enter_idle, | ||
54 | .exit_latency = 10, | ||
55 | .power_usage = 50, | ||
56 | .target_residency = 100, | ||
57 | .flags = CPUIDLE_FLAG_TIME_VALID, | ||
58 | .name = "MV CPU IDLE", | ||
59 | .desc = "CPU power down", | ||
60 | }, | ||
61 | .states[2] = { | ||
62 | .enter = armada_370_xp_enter_idle, | ||
63 | .exit_latency = 100, | ||
64 | .power_usage = 5, | ||
65 | .target_residency = 1000, | ||
66 | .flags = CPUIDLE_FLAG_TIME_VALID | | ||
67 | ARMADA_370_XP_FLAG_DEEP_IDLE, | ||
68 | .name = "MV CPU DEEP IDLE", | ||
69 | .desc = "CPU and L2 Fabric power down", | ||
70 | }, | ||
71 | .state_count = ARMADA_370_XP_MAX_STATES, | ||
72 | }; | ||
73 | |||
74 | static int armada_370_xp_cpuidle_probe(struct platform_device *pdev) | ||
75 | { | ||
76 | |||
77 | armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data); | ||
78 | return cpuidle_register(&armada_370_xp_idle_driver, NULL); | ||
79 | } | ||
80 | |||
81 | static struct platform_driver armada_370_xp_cpuidle_plat_driver = { | ||
82 | .driver = { | ||
83 | .name = "cpuidle-armada-370-xp", | ||
84 | .owner = THIS_MODULE, | ||
85 | }, | ||
86 | .probe = armada_370_xp_cpuidle_probe, | ||
87 | }; | ||
88 | |||
89 | module_platform_driver(armada_370_xp_cpuidle_plat_driver); | ||
90 | |||
91 | MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>"); | ||
92 | MODULE_DESCRIPTION("Armada 370/XP cpu idle driver"); | ||
93 | MODULE_LICENSE("GPL"); | ||