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