Skip to content

Commit 282048c

Browse files
committed
Merge branch 'refs/heads/bits/010-soc' into asahi-wip
2 parents 664910a + 95f67ad commit 282048c

14 files changed

Lines changed: 946 additions & 568 deletions

File tree

drivers/cpuidle/Kconfig.arm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,11 @@ config ARM_QCOM_SPM_CPUIDLE
130130
The Subsystem Power Manager (SPM) controls low power modes for the
131131
CPU and L2 cores. It interface with various system drivers to put
132132
the cores in low power modes.
133+
134+
config ARM_APPLE_CPUIDLE
135+
bool "Apple SoC CPU idle driver"
136+
depends on ARM64
137+
default ARCH_APPLE
138+
select CPU_IDLE_MULTIPLE_DRIVERS
139+
help
140+
Select this to enable cpuidle on Apple SoCs.

drivers/cpuidle/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
2626
obj-$(CONFIG_ARM_PSCI_CPUIDLE_DOMAIN) += cpuidle-psci-domain.o
2727
obj-$(CONFIG_ARM_TEGRA_CPUIDLE) += cpuidle-tegra.o
2828
obj-$(CONFIG_ARM_QCOM_SPM_CPUIDLE) += cpuidle-qcom-spm.o
29+
obj-$(CONFIG_ARM_APPLE_CPUIDLE) += cpuidle-apple.o
2930

3031
###############################################################################
3132
# MIPS drivers

drivers/cpuidle/cpuidle-apple.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
/*
3+
* Copyright The Asahi Linux Contributors
4+
*
5+
* CPU idle support for Apple SoCs
6+
*/
7+
8+
#include <linux/init.h>
9+
#include <linux/cpuidle.h>
10+
#include <linux/cpu_pm.h>
11+
#include <linux/platform_device.h>
12+
#include <linux/of.h>
13+
#include <asm/cpuidle.h>
14+
15+
enum idle_state {
16+
STATE_WFI,
17+
STATE_PWRDOWN,
18+
STATE_COUNT
19+
};
20+
21+
asm(
22+
".type apple_cpu_deep_wfi, @function\n"
23+
"apple_cpu_deep_wfi:\n"
24+
"str x30, [sp, #-16]!\n"
25+
"stp x28, x29, [sp, #-16]!\n"
26+
"stp x26, x27, [sp, #-16]!\n"
27+
"stp x24, x25, [sp, #-16]!\n"
28+
"stp x22, x23, [sp, #-16]!\n"
29+
"stp x20, x21, [sp, #-16]!\n"
30+
"stp x18, x19, [sp, #-16]!\n"
31+
32+
"mrs x0, s3_5_c15_c5_0\n"
33+
"orr x0, x0, #(3L << 24)\n"
34+
"msr s3_5_c15_c5_0, x0\n"
35+
36+
"1:\n"
37+
"dsb sy\n"
38+
"wfi\n"
39+
40+
"mrs x0, ISR_EL1\n"
41+
"cbz x0, 1b\n"
42+
43+
"mrs x0, s3_5_c15_c5_0\n"
44+
"bic x0, x0, #(1L << 24)\n"
45+
"msr s3_5_c15_c5_0, x0\n"
46+
47+
"ldp x18, x19, [sp], #16\n"
48+
"ldp x20, x21, [sp], #16\n"
49+
"ldp x22, x23, [sp], #16\n"
50+
"ldp x24, x25, [sp], #16\n"
51+
"ldp x26, x27, [sp], #16\n"
52+
"ldp x28, x29, [sp], #16\n"
53+
"ldr x30, [sp], #16\n"
54+
55+
"ret\n"
56+
);
57+
58+
void apple_cpu_deep_wfi(void);
59+
60+
static __cpuidle int apple_enter_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index)
61+
{
62+
/*
63+
* Deep WFI will clobber FP state, among other things.
64+
* The CPU PM notifier will take care of saving that and anything else
65+
* that needs to be notified of the CPU powering down.
66+
*/
67+
if (cpu_pm_enter())
68+
return -1;
69+
70+
switch(index) {
71+
case STATE_WFI:
72+
cpu_do_idle();
73+
break;
74+
case STATE_PWRDOWN:
75+
apple_cpu_deep_wfi();
76+
break;
77+
default:
78+
WARN_ON(1);
79+
break;
80+
}
81+
82+
cpu_pm_exit();
83+
84+
return index;
85+
}
86+
87+
static struct cpuidle_driver apple_idle_driver = {
88+
.name = "apple_idle",
89+
.owner = THIS_MODULE,
90+
.states = {
91+
[STATE_WFI] = {
92+
.enter = apple_enter_idle,
93+
.enter_s2idle = apple_enter_idle,
94+
.exit_latency = 1,
95+
.target_residency = 1,
96+
.power_usage = UINT_MAX,
97+
.name = "WFI",
98+
.desc = "CPU clock-gated",
99+
},
100+
[STATE_PWRDOWN] = {
101+
.enter = apple_enter_idle,
102+
.enter_s2idle = apple_enter_idle,
103+
.exit_latency = 10,
104+
.target_residency = 10000,
105+
.power_usage = 0,
106+
.name = "CPU PD",
107+
.desc = "CPU/cluster powered down",
108+
},
109+
},
110+
.safe_state_index = STATE_WFI,
111+
.state_count = STATE_COUNT,
112+
};
113+
114+
static int apple_cpuidle_probe(struct platform_device *pdev)
115+
{
116+
return cpuidle_register(&apple_idle_driver, NULL);
117+
}
118+
119+
static struct platform_driver apple_cpuidle_driver = {
120+
.driver = {
121+
.name = "cpuidle-apple",
122+
},
123+
.probe = apple_cpuidle_probe,
124+
};
125+
126+
static int __init apple_cpuidle_init(void)
127+
{
128+
struct platform_device *pdev;
129+
int ret;
130+
131+
ret = platform_driver_register(&apple_cpuidle_driver);
132+
if (ret)
133+
return ret;
134+
135+
if (!of_machine_is_compatible("apple,arm-platform"))
136+
return 0;
137+
138+
pdev = platform_device_register_simple("cpuidle-apple", -1, NULL, 0);
139+
if (IS_ERR(pdev)) {
140+
platform_driver_unregister(&apple_cpuidle_driver);
141+
return PTR_ERR(pdev);
142+
}
143+
144+
return 0;
145+
}
146+
device_initcall(apple_cpuidle_init);

drivers/mailbox/Kconfig

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,6 @@ menuconfig MAILBOX
88

99
if MAILBOX
1010

11-
config APPLE_MAILBOX
12-
tristate "Apple Mailbox driver"
13-
depends on ARCH_APPLE || (ARM64 && COMPILE_TEST)
14-
default ARCH_APPLE
15-
help
16-
Apple SoCs have various co-processors required for certain
17-
peripherals to work (NVMe, display controller, etc.). This
18-
driver adds support for the mailbox controller used to
19-
communicate with those.
20-
21-
Say Y here if you have a Apple SoC.
22-
2311
config ARM_MHU
2412
tristate "ARM MHU Mailbox"
2513
depends on ARM_AMBA

drivers/mailbox/Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,3 @@ obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o
6060
obj-$(CONFIG_SPRD_MBOX) += sprd-mailbox.o
6161

6262
obj-$(CONFIG_QCOM_IPCC) += qcom-ipcc.o
63-
64-
obj-$(CONFIG_APPLE_MAILBOX) += apple-mailbox.o

0 commit comments

Comments
 (0)