1 /*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <platform_def.h>
8
9 #include <arch.h>
10 #include <common/debug.h>
11 #include <lib/mmio.h>
12 #include <plat/common/platform.h>
13
14 #include <mt8173_def.h>
15 #include <spm.h>
16 #include <spm_hotplug.h>
17 #include <spm_mcdi.h>
18
19 /*
20 * System Power Manager (SPM) is a hardware module, which controls cpu or
21 * system power for different power scenarios using different firmware.
22 * This driver controls the cpu power in cpu idle power saving state.
23 */
24
25 #define WAKE_SRC_FOR_MCDI \
26 (WAKE_SRC_KP | WAKE_SRC_GPT | WAKE_SRC_EINT | \
27 WAKE_SRC_MD32 | WAKE_SRC_USB_CD | WAKE_SRC_USB_PDN | \
28 WAKE_SRC_AFE | WAKE_SRC_THERM | WAKE_SRC_CIRQ | \
29 WAKE_SRC_SYSPWREQ | WAKE_SRC_CPU_IRQ)
30 #define PCM_MCDI_HANDSHAKE_SYNC 0xbeefbeef
31 #define PCM_MCDI_HANDSHAKE_ACK 0xdeaddead
32 #define PCM_MCDI_UPDATE_INFORM 0xabcdabcd
33 #define PCM_MCDI_CKECK_DONE 0x12345678
34 #define PCM_MCDI_ALL_CORE_AWAKE 0x0
35 #define PCM_MCDI_OFFLOADED 0xaa55aa55
36 #define PCM_MCDI_CA72_CPUTOP_PWRCTL (0x1 << 16)
37 #define PCM_MCDI_CA53_CPUTOP_PWRCTL (0x1 << 17)
38 #define PCM_MCDI_CA72_PWRSTA_SHIFT 16
39 #define PCM_MCDI_CA53_PWRSTA_SHIFT 9
40
41 static const unsigned int mcdi_binary[] = {
42 0x1a10001f, 0x10006b04, 0x1890001f, 0x10006b6c, 0x1a40001f, 0x10006210,
43 0x18d0001f, 0x10006210, 0x81002001, 0xd82001c4, 0x17c07c1f, 0xa0900402,
44 0xc2401540, 0x17c07c1f, 0x81052001, 0xd8200284, 0x17c07c1f, 0xa0950402,
45 0xc2401b80, 0x17c07c1f, 0x1a40001f, 0x10006230, 0x18d0001f, 0x10006230,
46 0x8100a001, 0xd82003c4, 0x17c07c1f, 0xa0908402, 0xc2401540, 0x17c07c1f,
47 0x8105a001, 0xd8200484, 0x17c07c1f, 0xa0958402, 0xc2401b80, 0x17c07c1f,
48 0x1a40001f, 0x10006238, 0x18d0001f, 0x10006238, 0x81012001, 0xd82005c4,
49 0x17c07c1f, 0xa0910402, 0xc2401540, 0x17c07c1f, 0x81062001, 0xd8200684,
50 0x17c07c1f, 0xa0960402, 0xc2401b80, 0x17c07c1f, 0x1a40001f, 0x1000623c,
51 0x18d0001f, 0x1000623c, 0x8101a001, 0xd82007c4, 0x17c07c1f, 0xa0918402,
52 0xc2401540, 0x17c07c1f, 0x8106a001, 0xd8200884, 0x17c07c1f, 0xa0968402,
53 0xc2401b80, 0x17c07c1f, 0x1a40001f, 0x10006298, 0x18d0001f, 0x10006298,
54 0x81022001, 0xd82009c4, 0x17c07c1f, 0xa0920402, 0xc2401540, 0x17c07c1f,
55 0x81072001, 0xd8200a84, 0x17c07c1f, 0xa0970402, 0xc2401b80, 0x17c07c1f,
56 0x1a40001f, 0x1000629c, 0x18d0001f, 0x1000629c, 0x8102a001, 0xd8200bc4,
57 0x17c07c1f, 0xa0928402, 0xc2401540, 0x17c07c1f, 0x8107a001, 0xd8200c84,
58 0x17c07c1f, 0xa0978402, 0xc2401b80, 0x17c07c1f, 0x1a40001f, 0x100062c4,
59 0x18d0001f, 0x100062c4, 0x81032001, 0xd8200dc4, 0x17c07c1f, 0xa0930402,
60 0xc2401540, 0x17c07c1f, 0x81082001, 0xd8200e84, 0x17c07c1f, 0xa0980402,
61 0xc2401b80, 0x17c07c1f, 0x1a40001f, 0x100062c0, 0x18d0001f, 0x100062c0,
62 0x8103a001, 0xd8200fc4, 0x17c07c1f, 0xa0938402, 0xc2401540, 0x17c07c1f,
63 0x8108a001, 0xd8201084, 0x17c07c1f, 0xa0988402, 0xc2401b80, 0x17c07c1f,
64 0x1a40001f, 0x10006214, 0x18d0001f, 0x10006214, 0x81042001, 0xd82011c4,
65 0x17c07c1f, 0xa0940402, 0xc2401540, 0x17c07c1f, 0x81092001, 0xd8201284,
66 0x17c07c1f, 0xa0990402, 0xc2401b80, 0x17c07c1f, 0x1a40001f, 0x100062cc,
67 0x18d0001f, 0x100062cc, 0x8104a001, 0xd82013c4, 0x17c07c1f, 0xa0948402,
68 0xc2401540, 0x17c07c1f, 0x8109a001, 0xd8201484, 0x17c07c1f, 0xa0998402,
69 0xc2401b80, 0x17c07c1f, 0x1900001f, 0x10006b6c, 0x80802002, 0xe1000002,
70 0xf0000000, 0x17c07c1f, 0xa8c00003, 0x00000004, 0xe2400003, 0xa8c00003,
71 0x00000008, 0xe2400003, 0x1b80001f, 0x00000020, 0x88c00003, 0xffffffef,
72 0xe2400003, 0x88c00003, 0xfffffffd, 0xe2400003, 0xa8c00003, 0x00000001,
73 0xe2400003, 0x88c00003, 0xfffff0ff, 0xe2400003, 0x1b80001f, 0x20000080,
74 0x1a90001f, 0x10001220, 0x69200009, 0x1000623c, 0xd8001984, 0x17c07c1f,
75 0x69200009, 0x10006214, 0xd8001a64, 0x17c07c1f, 0xd0001b00, 0x17c07c1f,
76 0x1900001f, 0x10001220, 0x8a80000a, 0xfffffff9, 0xe100000a, 0xd0001b00,
77 0x17c07c1f, 0x1900001f, 0x10001220, 0x8a80000a, 0xff1fbfff, 0xe100000a,
78 0x1b80001f, 0x20000080, 0xf0000000, 0x17c07c1f, 0x1a90001f, 0x10001220,
79 0x69200009, 0x1000623c, 0xd8001d04, 0x17c07c1f, 0x69200009, 0x10006214,
80 0xd8001de4, 0x17c07c1f, 0xd0001e80, 0x17c07c1f, 0x1900001f, 0x10001220,
81 0xaa80000a, 0x00000006, 0xe100000a, 0xd0001e80, 0x17c07c1f, 0x1900001f,
82 0x10001220, 0xaa80000a, 0x00e04000, 0xe100000a, 0x1b80001f, 0x20000080,
83 0x69200009, 0x10006214, 0xd8001fe4, 0x17c07c1f, 0xa8c00003, 0x00000f00,
84 0xe2400003, 0xd0002040, 0x17c07c1f, 0xa8c00003, 0x00003f00, 0xe2400003,
85 0x1b80001f, 0x20000080, 0xa8c00003, 0x00000002, 0xe2400003, 0x88c00003,
86 0xfffffffe, 0xe2400003, 0xa8c00003, 0x00000010, 0xe2400003, 0x88c00003,
87 0xfffffffb, 0xe2400003, 0x88c00003, 0xfffffff7, 0xe2400003, 0xf0000000,
88 0x17c07c1f, 0xe2e00036, 0xe2e0003e, 0x1b80001f, 0x00000020, 0xe2e0003c,
89 0xe8208000, 0x10006244, 0x00000000, 0x1b80001f, 0x20000080, 0xe2e0007c,
90 0x1b80001f, 0x20000003, 0xe2e0005c, 0xe2e0004c, 0xe2e0004d, 0xf0000000,
91 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f, 0xe8208000, 0x10006244,
92 0x00000001, 0x1b80001f, 0x20000080, 0xe2e0002e, 0xe2e0003e, 0xe2e0003a,
93 0xe2e00032, 0x1b80001f, 0x00000020, 0xf0000000, 0x17c07c1f, 0xe2e00036,
94 0xe2e0003e, 0x1b80001f, 0x00000020, 0xe2e0003c, 0xe2a00000, 0x1b80001f,
95 0x20000080, 0xe2e0007c, 0x1b80001f, 0x20000003, 0xe2e0005c, 0xe2e0004c,
96 0xe2e0004d, 0xf0000000, 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f,
97 0xe2a00001, 0x1b80001f, 0x20000080, 0xe2e0002e, 0xe2e0003e, 0xe2e0003a,
98 0xe2e00032, 0xf0000000, 0x17c07c1f, 0xe2e00026, 0xe2e0002e, 0x1b80001f,
99 0x00000020, 0x1a00001f, 0x100062b4, 0x1910001f, 0x100062b4, 0x81322804,
100 0xe2000004, 0x81202804, 0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0000e,
101 0xe2e0000c, 0xe2e0000d, 0xf0000000, 0x17c07c1f, 0xe2e0002d, 0x1a00001f,
102 0x100062b4, 0x1910001f, 0x100062b4, 0xa1002804, 0xe2000004, 0xa1122804,
103 0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0002f, 0xe2e0002b, 0xe2e00023,
104 0x1b80001f, 0x00000020, 0xe2e00022, 0xf0000000, 0x17c07c1f, 0x1910001f,
105 0x1000660c, 0x1a10001f, 0x10006610, 0xa2002004, 0x89000008, 0x00030000,
106 0xd80036c4, 0x17c07c1f, 0x8207a001, 0xd82036c8, 0x17c07c1f, 0x1900001f,
107 0x1020020c, 0x1a10001f, 0x1020020c, 0xaa000008, 0x00000001, 0xe1000008,
108 0x1910001f, 0x1020020c, 0x81001001, 0xd8203184, 0x17c07c1f, 0x1910001f,
109 0x10006720, 0x820c9001, 0xd8203228, 0x17c07c1f, 0x1900001f, 0x10001220,
110 0x1a10001f, 0x10001220, 0xa21f0408, 0xe1000008, 0x1b80001f, 0x20000080,
111 0xe2e0006d, 0xe2e0002d, 0x1a00001f, 0x100062b8, 0x1910001f, 0x100062b8,
112 0xa9000004, 0x00000001, 0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0002c,
113 0xe2e0003c, 0xe2e0003e, 0xe2e0003a, 0xe2e00032, 0x1b80001f, 0x00000020,
114 0x1900001f, 0x10006404, 0x1a10001f, 0x10006404, 0xa2168408, 0xe1000008,
115 0xf0000000, 0x17c07c1f, 0x1a10001f, 0x10006610, 0x8207a001, 0xd8003e68,
116 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8a000008, 0x00003030, 0xb900010c,
117 0x01000001, 0xd8203e64, 0x17c07c1f, 0x1900001f, 0x10006404, 0x1a10001f,
118 0x10006404, 0x8a000008, 0x0000dfff, 0xe1000008, 0xe2e00036, 0xe2e0003e,
119 0x1b80001f, 0x00000020, 0xe2e0002e, 0x1a00001f, 0x100062b8, 0x1910001f,
120 0x100062b8, 0x89000004, 0x0000fffe, 0xe2000004, 0x1b80001f, 0x20000080,
121 0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0xe2e0004d, 0x1900001f, 0x10001220,
122 0x1a10001f, 0x10001220, 0x8a000008, 0xbfffffff, 0xe1000008, 0x1b80001f,
123 0x20000080, 0x1900001f, 0x1020020c, 0x1a10001f, 0x1020020c, 0x8a000008,
124 0xfffffffe, 0xe1000008, 0x1910001f, 0x1020020c, 0x81001001, 0xd8003dc4,
125 0x17c07c1f, 0xf0000000, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
126 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
127 0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001, 0x11407c1f, 0xe8208000,
128 0x10006310, 0x0b160008, 0x1900001f, 0x000f7bde, 0x1a00001f, 0x10200268,
129 0xe2000004, 0xe8208000, 0x10006600, 0x00000000, 0x69200006, 0xbeefbeef,
130 0xd8204584, 0x17c07c1f, 0x1910001f, 0x10006358, 0x810b1001, 0xd8004244,
131 0x17c07c1f, 0x1980001f, 0xdeaddead, 0x69200006, 0xabcdabcd, 0xd8204324,
132 0x17c07c1f, 0x88900001, 0x10006814, 0x1910001f, 0x10006400, 0x81271002,
133 0x1880001f, 0x10006600, 0xe0800004, 0x1910001f, 0x10006358, 0x810b1001,
134 0xd80044a4, 0x17c07c1f, 0x1980001f, 0x12345678, 0x60a07c05, 0x89100002,
135 0x10006600, 0x80801001, 0xd8007bc2, 0x17c07c1f, 0x1890001f, 0x10006b00,
136 0x82090801, 0xc8800008, 0x17c07c1f, 0x1b00001f, 0x3fffe7ff, 0x8a00000c,
137 0x3fffe7ff, 0xd82041c8, 0x17c07c1f, 0x1b80001f, 0xd0010000, 0x1a10001f,
138 0x10006720, 0x82002001, 0x82201408, 0xd8204988, 0x17c07c1f, 0x1a40001f,
139 0x10006200, 0x1a80001f, 0x1000625c, 0xc24028e0, 0x17c07c1f, 0xa1400405,
140 0x1a10001f, 0x10006720, 0x8200a001, 0x82209408, 0xd8204b28, 0x17c07c1f,
141 0x1a40001f, 0x10006218, 0x1a80001f, 0x10006264, 0xc24028e0, 0x17c07c1f,
142 0xa1508405, 0x1a10001f, 0x10006720, 0x82012001, 0x82211408, 0xd8204cc8,
143 0x17c07c1f, 0x1a40001f, 0x1000621c, 0x1a80001f, 0x1000626c, 0xc24028e0,
144 0x17c07c1f, 0xa1510405, 0x1a10001f, 0x10006720, 0x8201a001, 0x82219408,
145 0xd8204e68, 0x17c07c1f, 0x1a40001f, 0x10006220, 0x1a80001f, 0x10006274,
146 0xc24028e0, 0x17c07c1f, 0xa1518405, 0x1a10001f, 0x10006720, 0x82022001,
147 0x82221408, 0xd8204fe8, 0x17c07c1f, 0x1a40001f, 0x100062a0, 0x1280041f,
148 0xc2402cc0, 0x17c07c1f, 0xa1520405, 0x1a10001f, 0x10006720, 0x8202a001,
149 0x82229408, 0xd8205168, 0x17c07c1f, 0x1a40001f, 0x100062a4, 0x1290841f,
150 0xc2402cc0, 0x17c07c1f, 0xa1528405, 0x1a10001f, 0x10006720, 0x82032001,
151 0x82231408, 0xd8205248, 0x17c07c1f, 0xa1530405, 0x1a10001f, 0x10006720,
152 0x8203a001, 0x82239408, 0xd8205328, 0x17c07c1f, 0xa1538405, 0x1a10001f,
153 0x10006b00, 0x8108a001, 0xd8205e84, 0x17c07c1f, 0x1910001f, 0x1000660c,
154 0x1a10001f, 0x10006610, 0xa2002004, 0x89000008, 0x00001e00, 0xd8005944,
155 0x17c07c1f, 0x82042001, 0xd8205948, 0x17c07c1f, 0x1900001f, 0x1020002c,
156 0x1a10001f, 0x1020002c, 0xaa000008, 0x00000010, 0xe1000008, 0x1910001f,
157 0x10006720, 0x820c1001, 0xd8205628, 0x17c07c1f, 0x1900001f, 0x10001250,
158 0x1a10001f, 0x10001250, 0xa2110408, 0xe1000008, 0x1b80001f, 0x20000080,
159 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220, 0xa21e8408, 0xe1000008,
160 0x1b80001f, 0x20000080, 0x1a40001f, 0x10006208, 0xc24024e0, 0x17c07c1f,
161 0x1a10001f, 0x10006610, 0x82042001, 0xd8005e88, 0x17c07c1f, 0x1a10001f,
162 0x10006918, 0x8a000008, 0x00000f0f, 0xba00010c, 0x1fffe7ff, 0xd8205e88,
163 0x17c07c1f, 0x1a40001f, 0x10006208, 0xc24022a0, 0x17c07c1f, 0x1900001f,
164 0x10001250, 0x1a10001f, 0x10001250, 0x8a000008, 0xfffffffb, 0xe1000008,
165 0x1b80001f, 0x20000080, 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220,
166 0x8a000008, 0xdfffffff, 0xe1000008, 0x1b80001f, 0x20000080, 0x1900001f,
167 0x1020002c, 0x1a10001f, 0x1020002c, 0x8a000008, 0xffffffef, 0xe1000008,
168 0x1a10001f, 0x10006b00, 0x81082001, 0xd8205fa4, 0x17c07c1f, 0x1a40001f,
169 0x100062b0, 0xc2402f20, 0x17c07c1f, 0x1b80001f, 0x20000208, 0xd8207b8c,
170 0x17c07c1f, 0x1a40001f, 0x100062b0, 0xc2403700, 0x17c07c1f, 0x81001401,
171 0xd8206424, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81002001, 0xb1042081,
172 0xb900008c, 0x1fffe7ff, 0xd8206424, 0x17c07c1f, 0x1a40001f, 0x10006200,
173 0x1a80001f, 0x1000625c, 0xc24026e0, 0x17c07c1f, 0x89400005, 0xfffffffe,
174 0xe8208000, 0x10006f00, 0x00000000, 0xe8208000, 0x10006b30, 0x00000000,
175 0xe8208000, 0x100063e0, 0x00000001, 0x81009401, 0xd82067a4, 0x17c07c1f,
176 0x1a10001f, 0x10006918, 0x8100a001, 0xb104a081, 0xb900008c, 0x01000001,
177 0xd82067a4, 0x17c07c1f, 0x1a40001f, 0x10006218, 0x1a80001f, 0x10006264,
178 0xc24026e0, 0x17c07c1f, 0x89400005, 0xfffffffd, 0xe8208000, 0x10006f04,
179 0x00000000, 0xe8208000, 0x10006b34, 0x00000000, 0xe8208000, 0x100063e0,
180 0x00000002, 0x81011401, 0xd8206b24, 0x17c07c1f, 0x1a10001f, 0x10006918,
181 0x81012001, 0xb1052081, 0xb900008c, 0x01000001, 0xd8206b24, 0x17c07c1f,
182 0x1a40001f, 0x1000621c, 0x1a80001f, 0x1000626c, 0xc24026e0, 0x17c07c1f,
183 0x89400005, 0xfffffffb, 0xe8208000, 0x10006f08, 0x00000000, 0xe8208000,
184 0x10006b38, 0x00000000, 0xe8208000, 0x100063e0, 0x00000004, 0x81019401,
185 0xd8206ea4, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8101a001, 0xb105a081,
186 0xb900008c, 0x01000001, 0xd8206ea4, 0x17c07c1f, 0x1a40001f, 0x10006220,
187 0x1a80001f, 0x10006274, 0xc24026e0, 0x17c07c1f, 0x89400005, 0xfffffff7,
188 0xe8208000, 0x10006f0c, 0x00000000, 0xe8208000, 0x10006b3c, 0x00000000,
189 0xe8208000, 0x100063e0, 0x00000008, 0x1a10001f, 0x10006610, 0x8207a001,
190 0xd8207608, 0x17c07c1f, 0x81021401, 0xd82072a4, 0x17c07c1f, 0x1a10001f,
191 0x10006918, 0x81022001, 0xb1062081, 0xb900008c, 0x01000001, 0xd82072a4,
192 0x17c07c1f, 0x1a40001f, 0x100062a0, 0x1280041f, 0xc2402a60, 0x17c07c1f,
193 0x89400005, 0xffffffef, 0xe8208000, 0x10006f10, 0x00000000, 0xe8208000,
194 0x10006b40, 0x00000000, 0xe8208000, 0x100063e0, 0x00000010, 0x81029401,
195 0xd8207604, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8102a001, 0xb106a081,
196 0xb900008c, 0x01000001, 0xd8207604, 0x17c07c1f, 0x1a40001f, 0x100062a4,
197 0x1290841f, 0xc2402a60, 0x17c07c1f, 0x89400005, 0xffffffdf, 0xe8208000,
198 0x10006f14, 0x00000000, 0xe8208000, 0x10006b44, 0x00000000, 0xe8208000,
199 0x100063e0, 0x00000020, 0x81031401, 0xd82078c4, 0x17c07c1f, 0x1a10001f,
200 0x10006918, 0x81032001, 0xb1072081, 0xb900008c, 0x01000001, 0xd82078c4,
201 0x17c07c1f, 0x89400005, 0xffffffbf, 0xe8208000, 0x10006f18, 0x00000000,
202 0xe8208000, 0x10006b48, 0x00000000, 0xe8208000, 0x100063e0, 0x00000040,
203 0x81039401, 0xd8207b84, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8103a001,
204 0xb107a081, 0xb900008c, 0x01000001, 0xd8207b84, 0x17c07c1f, 0x89400005,
205 0xffffff7f, 0xe8208000, 0x10006f1c, 0x00000000, 0xe8208000, 0x10006b4c,
206 0x00000000, 0xe8208000, 0x100063e0, 0x00000080, 0xd00041c0, 0x17c07c1f,
207 0xe8208000, 0x10006600, 0x00000000, 0x1ac0001f, 0x55aa55aa, 0x1940001f,
208 0xaa55aa55, 0x1b80001f, 0x00001000, 0xf0000000, 0x17c07c1f
209 };
210
211 static const struct pcm_desc mcdi_pcm = {
212 .version = "pcm_mcdi_mt8173_20160401_v1",
213 .base = mcdi_binary,
214 .size = 1001,
215 .sess = 2,
216 .replace = 0,
217 };
218
219 static struct pwr_ctrl mcdi_ctrl = {
220 .wake_src = WAKE_SRC_FOR_MCDI,
221 .wake_src_md32 = 0,
222 .wfi_op = WFI_OP_OR,
223 .mcusys_idle_mask = 1,
224 .ca7top_idle_mask = 1,
225 .ca15top_idle_mask = 1,
226 .disp_req_mask = 1,
227 .mfg_req_mask = 1,
228 .md32_req_mask = 1,
229 };
230
231 static const struct spm_lp_scen spm_mcdi = {
232 .pcmdesc = &mcdi_pcm,
233 .pwrctrl = &mcdi_ctrl,
234 };
235
spm_mcdi_cpu_wake_up_event(int wake_up_event,int disable_dormant_power)236 void spm_mcdi_cpu_wake_up_event(int wake_up_event, int disable_dormant_power)
237 {
238 if (((mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) & 0x1) == 1)
239 && ((mmio_read_32(SPM_CLK_CON) & CC_DISABLE_DORM_PWR) == 0)) {
240 /* MCDI is offload? */
241 INFO("%s: SPM_SLEEP_CPU_WAKEUP_EVENT:%x, SPM_CLK_CON %x",
242 __func__, mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT),
243 mmio_read_32(SPM_CLK_CON));
244 return;
245 }
246 /* Inform SPM that CPU wants to program CPU_WAKEUP_EVENT and
247 * DISABLE_CPU_DROM */
248 mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_HANDSHAKE_SYNC);
249 mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
250 mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
251
252 /* Wait SPM's response, can't use sleep api */
253 while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_HANDSHAKE_ACK)
254 ;
255
256 if (disable_dormant_power) {
257 mmio_setbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
258 while (mmio_read_32(SPM_CLK_CON) !=
259 (mmio_read_32(SPM_CLK_CON) | CC_DISABLE_DORM_PWR))
260 ;
261
262 } else {
263 mmio_clrbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
264 while (mmio_read_32(SPM_CLK_CON) !=
265 (mmio_read_32(SPM_CLK_CON) & ~CC_DISABLE_DORM_PWR))
266 ;
267 }
268
269 mmio_write_32(SPM_SLEEP_CPU_WAKEUP_EVENT, wake_up_event);
270
271 while (mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) != wake_up_event)
272 ;
273
274 /* Inform SPM to see updated setting */
275 mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_UPDATE_INFORM);
276 mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
277 mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
278
279 while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_CKECK_DONE)
280 ;
281 /* END OF sequence */
282
283 mmio_write_32(SPM_PCM_REG_DATA_INI, 0x0);
284 mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
285 mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
286 }
287
spm_mcdi_wakeup_all_cores(void)288 void spm_mcdi_wakeup_all_cores(void)
289 {
290 if (is_mcdi_ready() == 0)
291 return;
292
293 spm_mcdi_cpu_wake_up_event(1, 1);
294 while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_ALL_CORE_AWAKE)
295 ;
296 spm_mcdi_cpu_wake_up_event(1, 0);
297 while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_OFFLOADED)
298 ;
299
300 spm_clean_after_wakeup();
301 clear_all_ready();
302 }
303
spm_mcdi_wfi_sel_enter(unsigned long mpidr)304 static void spm_mcdi_wfi_sel_enter(unsigned long mpidr)
305 {
306 int core_id_val = mpidr & MPIDR_CPU_MASK;
307 int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
308
309 /* SPM WFI Select by core number */
310 if (cluster_id) {
311 switch (core_id_val) {
312 case 0:
313 mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 1);
314 mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 1);
315 break;
316 case 1:
317 mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 1);
318 mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 1);
319 break;
320 case 2:
321 mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 1);
322 mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 1);
323 break;
324 case 3:
325 mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 1);
326 mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 1);
327 break;
328 default:
329 break;
330 }
331 } else {
332 switch (core_id_val) {
333 case 0:
334 mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 1);
335 mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 1);
336 break;
337 case 1:
338 mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 1);
339 mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 1);
340 break;
341 case 2:
342 mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 1);
343 mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 1);
344 break;
345 case 3:
346 mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 1);
347 mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 1);
348 break;
349 default:
350 break;
351 }
352 }
353 }
354
spm_mcdi_wfi_sel_leave(unsigned long mpidr)355 static void spm_mcdi_wfi_sel_leave(unsigned long mpidr)
356 {
357 int core_id_val = mpidr & MPIDR_CPU_MASK;
358 int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
359
360 /* SPM WFI Select by core number */
361 if (cluster_id) {
362 switch (core_id_val) {
363 case 0:
364 mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 0);
365 mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 0);
366 break;
367 case 1:
368 mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 0);
369 mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 0);
370 break;
371 case 2:
372 mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 0);
373 mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 0);
374 break;
375 case 3:
376 mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 0);
377 mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 0);
378 break;
379 default:
380 break;
381 }
382 } else {
383 switch (core_id_val) {
384 case 0:
385 mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 0);
386 mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 0);
387 break;
388 case 1:
389 mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 0);
390 mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 0);
391 break;
392 case 2:
393 mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 0);
394 mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 0);
395 break;
396 case 3:
397 mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 0);
398 mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 0);
399 break;
400 default:
401 break;
402 }
403 }
404 }
405
spm_mcdi_set_cputop_pwrctrl_for_cluster_off(unsigned long mpidr)406 static void spm_mcdi_set_cputop_pwrctrl_for_cluster_off(unsigned long mpidr)
407 {
408 unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
409 unsigned long cpu_id = mpidr & MPIDR_CPU_MASK;
410 unsigned int pwr_status, shift, i, flag = 0;
411
412 pwr_status = mmio_read_32(SPM_PWR_STATUS) |
413 mmio_read_32(SPM_PWR_STATUS_2ND);
414
415 if (cluster_id) {
416 for (i = 0; i < PLATFORM_CLUSTER1_CORE_COUNT; i++) {
417 if (i == cpu_id)
418 continue;
419 shift = i + PCM_MCDI_CA72_PWRSTA_SHIFT;
420 flag |= (pwr_status & (1 << shift)) >> shift;
421 }
422 if (!flag)
423 mmio_setbits_32(SPM_PCM_RESERVE,
424 PCM_MCDI_CA72_CPUTOP_PWRCTL);
425 } else {
426 for (i = 0; i < PLATFORM_CLUSTER0_CORE_COUNT; i++) {
427 if (i == cpu_id)
428 continue;
429 shift = i + PCM_MCDI_CA53_PWRSTA_SHIFT;
430 flag |= (pwr_status & (1 << shift)) >> shift;
431 }
432 if (!flag)
433 mmio_setbits_32(SPM_PCM_RESERVE,
434 PCM_MCDI_CA53_CPUTOP_PWRCTL);
435 }
436 }
437
spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(unsigned long mpidr)438 static void spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(unsigned long mpidr)
439 {
440 unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
441
442 if (cluster_id)
443 mmio_clrbits_32(SPM_PCM_RESERVE,
444 PCM_MCDI_CA72_CPUTOP_PWRCTL);
445 else
446 mmio_clrbits_32(SPM_PCM_RESERVE,
447 PCM_MCDI_CA53_CPUTOP_PWRCTL);
448 }
449
spm_mcdi_prepare_for_mtcmos(void)450 void spm_mcdi_prepare_for_mtcmos(void)
451 {
452 const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
453 struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
454
455 if (is_mcdi_ready() == 0) {
456 if (is_hotplug_ready() == 1)
457 spm_clear_hotplug();
458 set_pwrctrl_pcm_flags(pwrctrl, 0);
459 spm_reset_and_init_pcm();
460 spm_kick_im_to_fetch(pcmdesc);
461 spm_set_power_control(pwrctrl);
462 spm_set_wakeup_event(pwrctrl);
463 spm_kick_pcm_to_run(pwrctrl);
464 set_mcdi_ready();
465 }
466 }
467
spm_mcdi_prepare_for_off_state(unsigned long mpidr,unsigned int afflvl)468 void spm_mcdi_prepare_for_off_state(unsigned long mpidr, unsigned int afflvl)
469 {
470 const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
471 struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
472
473 spm_lock_get();
474 if (is_mcdi_ready() == 0) {
475 if (is_hotplug_ready() == 1)
476 spm_clear_hotplug();
477 set_pwrctrl_pcm_flags(pwrctrl, 0);
478 spm_reset_and_init_pcm();
479 spm_kick_im_to_fetch(pcmdesc);
480 spm_set_power_control(pwrctrl);
481 spm_set_wakeup_event(pwrctrl);
482 spm_kick_pcm_to_run(pwrctrl);
483 set_mcdi_ready();
484 }
485 spm_mcdi_wfi_sel_enter(mpidr);
486 if (afflvl == MPIDR_AFFLVL1)
487 spm_mcdi_set_cputop_pwrctrl_for_cluster_off(mpidr);
488 spm_lock_release();
489 }
490
spm_mcdi_finish_for_on_state(unsigned long mpidr,unsigned int afflvl)491 void spm_mcdi_finish_for_on_state(unsigned long mpidr, unsigned int afflvl)
492 {
493 unsigned long linear_id;
494
495 linear_id = ((mpidr & MPIDR_CLUSTER_MASK) >> 6) |
496 (mpidr & MPIDR_CPU_MASK);
497
498 spm_lock_get();
499 spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(mpidr);
500 spm_mcdi_wfi_sel_leave(mpidr);
501 mmio_write_32(SPM_PCM_SW_INT_CLEAR, (0x1 << linear_id));
502 spm_lock_release();
503 }
504