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