xref: /rk3399_ARM-atf/plat/mediatek/mt8173/drivers/spm/spm_mcdi.c (revision 3105f7ba9a3a9f6f0e78761e8bdd4da621254730)
1 /*
2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 #include <arch.h>
31 #include <debug.h>
32 #include <mmio.h>
33 #include <mt8173_def.h>
34 #include <platform.h>
35 #include <platform_def.h>
36 #include <spm.h>
37 #include <spm_hotplug.h>
38 #include <spm_mcdi.h>
39 
40 /*
41  * System Power Manager (SPM) is a hardware module, which controls cpu or
42  * system power for different power scenarios using different firmware.
43  * This driver controls the cpu power in cpu idle power saving state.
44  */
45 
46 #define WAKE_SRC_FOR_MCDI \
47 	(WAKE_SRC_KP | WAKE_SRC_GPT | WAKE_SRC_EINT |		\
48 	 WAKE_SRC_MD32 | WAKE_SRC_USB_CD | WAKE_SRC_USB_PDN |	\
49 	 WAKE_SRC_AFE | WAKE_SRC_THERM | WAKE_SRC_CIRQ |	\
50 	 WAKE_SRC_SYSPWREQ | WAKE_SRC_CPU_IRQ)
51 #define PCM_MCDI_HANDSHAKE_SYNC	0xbeefbeef
52 #define PCM_MCDI_HANDSHAKE_ACK	0xdeaddead
53 #define PCM_MCDI_UPDATE_INFORM	0xabcdabcd
54 #define PCM_MCDI_CKECK_DONE	0x12345678
55 #define PCM_MCDI_ALL_CORE_AWAKE	0x0
56 #define PCM_MCDI_OFFLOADED	0xaa55aa55
57 #define PCM_MCDI_CA72_CPUTOP_PWRCTL	(0x1 << 16)
58 #define PCM_MCDI_CA53_CPUTOP_PWRCTL	(0x1 << 17)
59 #define PCM_MCDI_CA72_PWRSTA_SHIFT	16
60 #define PCM_MCDI_CA53_PWRSTA_SHIFT	9
61 
62 static const unsigned int mcdi_binary[] = {
63 	0x1a10001f, 0x10006b04, 0x1890001f, 0x10006b6c, 0x1a40001f, 0x10006210,
64 	0x18d0001f, 0x10006210, 0x81002001, 0xd82001c4, 0x17c07c1f, 0xa0900402,
65 	0xc2401520, 0x17c07c1f, 0x81052001, 0xd8200284, 0x17c07c1f, 0x80b00402,
66 	0xc2401b60, 0x17c07c1f, 0x1a40001f, 0x10006230, 0x18d0001f, 0x10006230,
67 	0x8100a001, 0xd82003c4, 0x17c07c1f, 0xa0908402, 0xc2401520, 0x17c07c1f,
68 	0x8105a001, 0xd8200484, 0x17c07c1f, 0x80b08402, 0xc2401b60, 0x17c07c1f,
69 	0x1a40001f, 0x10006238, 0x18d0001f, 0x10006238, 0x81012001, 0xd82005c4,
70 	0x17c07c1f, 0xa0910402, 0xc2401520, 0x17c07c1f, 0x81062001, 0xd8200684,
71 	0x17c07c1f, 0x80b10402, 0xc2401b60, 0x17c07c1f, 0x1a40001f, 0x1000623c,
72 	0x18d0001f, 0x1000623c, 0x8101a001, 0xd82007c4, 0x17c07c1f, 0xa0918402,
73 	0xc2401520, 0x17c07c1f, 0x8106a001, 0xd8200884, 0x17c07c1f, 0x80b18402,
74 	0xc2401b60, 0x17c07c1f, 0x1a40001f, 0x10006298, 0x18d0001f, 0x10006298,
75 	0x81022001, 0xd82009c4, 0x17c07c1f, 0xa0920402, 0xc2401520, 0x17c07c1f,
76 	0x81072001, 0xd8200a84, 0x17c07c1f, 0x80b20402, 0xc2401b60, 0x17c07c1f,
77 	0x1a40001f, 0x1000629c, 0x18d0001f, 0x1000629c, 0x8102a001, 0xd8200bc4,
78 	0x17c07c1f, 0xa0928402, 0xc2401520, 0x17c07c1f, 0x8107a001, 0xd8200c84,
79 	0x17c07c1f, 0x80b28402, 0xc2401b60, 0x17c07c1f, 0x1a40001f, 0x100062c4,
80 	0x18d0001f, 0x100062c4, 0x81032001, 0xd8200dc4, 0x17c07c1f, 0xa0930402,
81 	0xc2401520, 0x17c07c1f, 0x81082001, 0xd8200e84, 0x17c07c1f, 0x80b30402,
82 	0xc2401b60, 0x17c07c1f, 0x1a40001f, 0x100062c0, 0x18d0001f, 0x100062c0,
83 	0x8103a001, 0xd8200fc4, 0x17c07c1f, 0xa0938402, 0xc2401520, 0x17c07c1f,
84 	0x8108a001, 0xd8201084, 0x17c07c1f, 0x80b38402, 0xc2401b60, 0x17c07c1f,
85 	0x1a40001f, 0x10006214, 0x18d0001f, 0x10006214, 0x81042001, 0xd82011c4,
86 	0x17c07c1f, 0xa0940402, 0xc2401520, 0x17c07c1f, 0x81092001, 0xd8201284,
87 	0x17c07c1f, 0x80b40402, 0xc2401b60, 0x17c07c1f, 0x1a40001f, 0x100062cc,
88 	0x18d0001f, 0x100062cc, 0x8104a001, 0xd82013c4, 0x17c07c1f, 0xa0948402,
89 	0xc2401520, 0x17c07c1f, 0x8109a001, 0xd8201484, 0x17c07c1f, 0x80b48402,
90 	0xc2401b60, 0x17c07c1f, 0x1900001f, 0x10006b6c, 0xe1000002, 0xf0000000,
91 	0x17c07c1f, 0xa8c00003, 0x00000004, 0xe2400003, 0xa8c00003, 0x00000008,
92 	0xe2400003, 0x1b80001f, 0x00000020, 0x88c00003, 0xffffffef, 0xe2400003,
93 	0x88c00003, 0xfffffffd, 0xe2400003, 0xa8c00003, 0x00000001, 0xe2400003,
94 	0x88c00003, 0xfffff0ff, 0xe2400003, 0x1b80001f, 0x20000080, 0x1a90001f,
95 	0x10001220, 0x69200009, 0x1000623c, 0xd8001964, 0x17c07c1f, 0x69200009,
96 	0x10006214, 0xd8001a44, 0x17c07c1f, 0xd0001ae0, 0x17c07c1f, 0x1900001f,
97 	0x10001220, 0x8a80000a, 0xfffffff9, 0xe100000a, 0xd0001ae0, 0x17c07c1f,
98 	0x1900001f, 0x10001220, 0x8a80000a, 0xff1fbfff, 0xe100000a, 0x1b80001f,
99 	0x20000080, 0xf0000000, 0x17c07c1f, 0x1a90001f, 0x10001220, 0x69200009,
100 	0x1000623c, 0xd8001ce4, 0x17c07c1f, 0x69200009, 0x10006214, 0xd8001dc4,
101 	0x17c07c1f, 0xd0001e60, 0x17c07c1f, 0x1900001f, 0x10001220, 0xaa80000a,
102 	0x00000006, 0xe100000a, 0xd0001e60, 0x17c07c1f, 0x1900001f, 0x10001220,
103 	0xaa80000a, 0x00e04000, 0xe100000a, 0x1b80001f, 0x20000080, 0x69200009,
104 	0x10006214, 0xd8001fc4, 0x17c07c1f, 0xa8c00003, 0x00000f00, 0xe2400003,
105 	0xd0002020, 0x17c07c1f, 0xa8c00003, 0x00003f00, 0xe2400003, 0x1b80001f,
106 	0x20000080, 0xa8c00003, 0x00000002, 0xe2400003, 0x88c00003, 0xfffffffe,
107 	0xe2400003, 0xa8c00003, 0x00000010, 0xe2400003, 0x88c00003, 0xfffffffb,
108 	0xe2400003, 0x88c00003, 0xfffffff7, 0xe2400003, 0xf0000000, 0x17c07c1f,
109 	0xe2e00036, 0xe2e0003e, 0x1b80001f, 0x00000020, 0xe2e0003c, 0xe8208000,
110 	0x10006244, 0x00000000, 0x1b80001f, 0x20000080, 0xe2e0007c, 0x1b80001f,
111 	0x20000003, 0xe2e0005c, 0xe2e0004c, 0xe2e0004d, 0xf0000000, 0x17c07c1f,
112 	0xe2e0004f, 0xe2e0006f, 0xe2e0002f, 0xe8208000, 0x10006244, 0x00000001,
113 	0x1b80001f, 0x20000080, 0xe2e0002e, 0xe2e0003e, 0xe2e0003a, 0xe2e00032,
114 	0x1b80001f, 0x00000020, 0x1910001f, 0x10006b6c, 0x09000004, 0x00100000,
115 	0x1a10001f, 0x10006b6c, 0xe2000004, 0xf0000000, 0x17c07c1f, 0xe2e00036,
116 	0xe2e0003e, 0x1b80001f, 0x00000020, 0xe2e0003c, 0xe2a00000, 0x1b80001f,
117 	0x20000080, 0xe2e0007c, 0x1b80001f, 0x20000003, 0xe2e0005c, 0xe2e0004c,
118 	0xe2e0004d, 0xf0000000, 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f,
119 	0xe2a00001, 0x1b80001f, 0x20000080, 0xe2e0002e, 0xe2e0003e, 0xe2e0003a,
120 	0xe2e00032, 0xf0000000, 0x17c07c1f, 0xe2e00026, 0xe2e0002e, 0x1b80001f,
121 	0x00000020, 0x1a00001f, 0x100062b4, 0x1910001f, 0x100062b4, 0x81322804,
122 	0xe2000004, 0x81202804, 0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0000e,
123 	0xe2e0000c, 0xe2e0000d, 0xf0000000, 0x17c07c1f, 0xe2e0002d, 0x1a00001f,
124 	0x100062b4, 0x1910001f, 0x100062b4, 0xa1002804, 0xe2000004, 0xa1122804,
125 	0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0002f, 0xe2e0002b, 0xe2e00023,
126 	0x1b80001f, 0x00000020, 0xe2e00022, 0xf0000000, 0x17c07c1f, 0x1900001f,
127 	0x1020020c, 0x1a10001f, 0x1020020c, 0xaa000008, 0x00000001, 0xe1000008,
128 	0x1910001f, 0x10006720, 0x820c9001, 0xd82030c8, 0x17c07c1f, 0x1900001f,
129 	0x10001220, 0x1a10001f, 0x10001220, 0xa21f0408, 0xe1000008, 0x1b80001f,
130 	0x20000080, 0xe2e0006d, 0xe2e0002d, 0x1a00001f, 0x100062b8, 0x1910001f,
131 	0x100062b8, 0xa9000004, 0x00000001, 0xe2000004, 0x1b80001f, 0x20000080,
132 	0xe2e0002c, 0xe2e0003c, 0xe2e0003e, 0xe2e0003a, 0xe2e00032, 0x1b80001f,
133 	0x00000020, 0x1900001f, 0x10006404, 0x1a10001f, 0x10006404, 0xa2168408,
134 	0xe1000008, 0xf0000000, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8a000008,
135 	0x00003030, 0xb900010c, 0x01000001, 0xd8203bc4, 0x17c07c1f, 0x1900001f,
136 	0x10006404, 0x1a10001f, 0x10006404, 0x8a000008, 0x0000dfff, 0xe1000008,
137 	0xe2e00036, 0xe2e0003e, 0x1b80001f, 0x00000020, 0xe2e0002e, 0x1a00001f,
138 	0x100062b8, 0x1910001f, 0x100062b8, 0x89000004, 0x0000fffe, 0xe2000004,
139 	0x1b80001f, 0x20000080, 0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0xe2e0004d,
140 	0x1900001f, 0x10001220, 0x1a10001f, 0x10001220, 0x8a000008, 0xbfffffff,
141 	0xe1000008, 0x1b80001f, 0x20000080, 0x1900001f, 0x1020020c, 0x1a10001f,
142 	0x1020020c, 0x8a000008, 0xfffffffe, 0xe1000008, 0xf0000000, 0x17c07c1f,
143 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
144 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
145 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
146 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
147 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
148 	0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001, 0x11407c1f, 0xe8208000,
149 	0x10006b6c, 0xa0000000, 0xe8208000, 0x10006310, 0x0b160008, 0x1900001f,
150 	0x000f7bde, 0x1a00001f, 0x10200268, 0xe2000004, 0xe8208000, 0x10006600,
151 	0x00000000, 0x69200006, 0xbeefbeef, 0xd82045e4, 0x17c07c1f, 0x1910001f,
152 	0x10006358, 0x810b1001, 0xd80042a4, 0x17c07c1f, 0x1980001f, 0xdeaddead,
153 	0x69200006, 0xabcdabcd, 0xd8204384, 0x17c07c1f, 0x88900001, 0x10006814,
154 	0x1910001f, 0x10006400, 0x81271002, 0x1880001f, 0x10006600, 0xe0800004,
155 	0x1910001f, 0x10006358, 0x810b1001, 0xd8004504, 0x17c07c1f, 0x1980001f,
156 	0x12345678, 0x60a07c05, 0x89100002, 0x10006600, 0x80801001, 0xd8007e02,
157 	0x17c07c1f, 0x1890001f, 0x10006b00, 0x82090801, 0xc8800008, 0x17c07c1f,
158 	0x1b00001f, 0x3fffe7ff, 0x8a00000c, 0x3fffe7ff, 0xd8204228, 0x17c07c1f,
159 	0x1b80001f, 0xd0010000, 0x1a10001f, 0x10006720, 0x82002001, 0x82201408,
160 	0xd82049e8, 0x17c07c1f, 0x1a40001f, 0x10006200, 0x1a80001f, 0x1000625c,
161 	0xc24029a0, 0x17c07c1f, 0xa1400405, 0x1a10001f, 0x10006720, 0x8200a001,
162 	0x82209408, 0xd8204b88, 0x17c07c1f, 0x1a40001f, 0x10006218, 0x1a80001f,
163 	0x10006264, 0xc24029a0, 0x17c07c1f, 0xa1508405, 0x1a10001f, 0x10006720,
164 	0x82012001, 0x82211408, 0xd8204d28, 0x17c07c1f, 0x1a40001f, 0x1000621c,
165 	0x1a80001f, 0x1000626c, 0xc24029a0, 0x17c07c1f, 0xa1510405, 0x1a10001f,
166 	0x10006720, 0x8201a001, 0x82219408, 0xd8204ec8, 0x17c07c1f, 0x1a40001f,
167 	0x10006220, 0x1a80001f, 0x10006274, 0xc24029a0, 0x17c07c1f, 0xa1518405,
168 	0x1a10001f, 0x10006720, 0x82022001, 0x82221408, 0xd8205048, 0x17c07c1f,
169 	0x1a40001f, 0x100062a0, 0x1280041f, 0xc2402d80, 0x17c07c1f, 0xa1520405,
170 	0x1a10001f, 0x10006720, 0x8202a001, 0x82229408, 0xd82051c8, 0x17c07c1f,
171 	0x1a40001f, 0x100062a4, 0x1290841f, 0xc2402d80, 0x17c07c1f, 0xa1528405,
172 	0x1a10001f, 0x10006720, 0x82032001, 0x82231408, 0xd82052a8, 0x17c07c1f,
173 	0xa1530405, 0x1a10001f, 0x10006720, 0x8203a001, 0x82239408, 0xd8205388,
174 	0x17c07c1f, 0xa1538405, 0x1a10001f, 0x10006b00, 0x8108a001, 0xd8205ec4,
175 	0x17c07c1f, 0x1a10001f, 0x10006610, 0x8104a001, 0xb1052081, 0xb105a081,
176 	0xb1062081, 0xd8005984, 0x17c07c1f, 0x81042001, 0xd8205984, 0x17c07c1f,
177 	0x1900001f, 0x1020002c, 0x1a10001f, 0x1020002c, 0xaa000008, 0x00000010,
178 	0xe1000008, 0x1910001f, 0x10006720, 0x820c1001, 0xd8205668, 0x17c07c1f,
179 	0x1900001f, 0x10001250, 0x1a10001f, 0x10001250, 0xa2110408, 0xe1000008,
180 	0x1b80001f, 0x20000080, 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220,
181 	0xa21e8408, 0xe1000008, 0x1b80001f, 0x20000080, 0x1a40001f, 0x10006208,
182 	0xc24024c0, 0x17c07c1f, 0x1910001f, 0x10006610, 0x81041001, 0xd8005ec4,
183 	0x17c07c1f, 0x1a10001f, 0x10006918, 0x8a000008, 0x00000f0f, 0xb900010c,
184 	0x1fffe7ff, 0xd8205ec4, 0x17c07c1f, 0x1a40001f, 0x10006208, 0xc2402280,
185 	0x17c07c1f, 0x1900001f, 0x10001250, 0x1a10001f, 0x10001250, 0x8a000008,
186 	0xfffffffb, 0xe1000008, 0x1b80001f, 0x20000080, 0x1900001f, 0x10001220,
187 	0x1a10001f, 0x10001220, 0x8a000008, 0xdfffffff, 0xe1000008, 0x1b80001f,
188 	0x20000080, 0x1900001f, 0x1020002c, 0x1a10001f, 0x1020002c, 0x8a000008,
189 	0xffffffef, 0xe1000008, 0x1a10001f, 0x10006b00, 0x81082001, 0xd8206144,
190 	0x17c07c1f, 0x1a10001f, 0x10006610, 0x81082001, 0xb108a081, 0xd8006144,
191 	0x17c07c1f, 0x1a10001f, 0x10006610, 0x8107a001, 0xd8206144, 0x17c07c1f,
192 	0x1a40001f, 0x100062b0, 0xc2402fe0, 0x17c07c1f, 0x1b80001f, 0x20000208,
193 	0xd8207dcc, 0x17c07c1f, 0x1910001f, 0x10006610, 0x81079001, 0xd80062e4,
194 	0x17c07c1f, 0x1a40001f, 0x100062b0, 0xc24035a0, 0x17c07c1f, 0x81001401,
195 	0xd8206664, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81002001, 0xb1042081,
196 	0xb900008c, 0x1fffe7ff, 0xd8206664, 0x17c07c1f, 0x1a40001f, 0x10006200,
197 	0x1a80001f, 0x1000625c, 0xc24027a0, 0x17c07c1f, 0x89400005, 0xfffffffe,
198 	0xe8208000, 0x10006f00, 0x00000000, 0xe8208000, 0x10006b30, 0x00000000,
199 	0xe8208000, 0x100063e0, 0x00000001, 0x81009401, 0xd82069e4, 0x17c07c1f,
200 	0x1a10001f, 0x10006918, 0x8100a001, 0xb104a081, 0xb900008c, 0x01000001,
201 	0xd82069e4, 0x17c07c1f, 0x1a40001f, 0x10006218, 0x1a80001f, 0x10006264,
202 	0xc24027a0, 0x17c07c1f, 0x89400005, 0xfffffffd, 0xe8208000, 0x10006f04,
203 	0x00000000, 0xe8208000, 0x10006b34, 0x00000000, 0xe8208000, 0x100063e0,
204 	0x00000002, 0x81011401, 0xd8206d64, 0x17c07c1f, 0x1a10001f, 0x10006918,
205 	0x81012001, 0xb1052081, 0xb900008c, 0x01000001, 0xd8206d64, 0x17c07c1f,
206 	0x1a40001f, 0x1000621c, 0x1a80001f, 0x1000626c, 0xc24027a0, 0x17c07c1f,
207 	0x89400005, 0xfffffffb, 0xe8208000, 0x10006f08, 0x00000000, 0xe8208000,
208 	0x10006b38, 0x00000000, 0xe8208000, 0x100063e0, 0x00000004, 0x81019401,
209 	0xd82070e4, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8101a001, 0xb105a081,
210 	0xb900008c, 0x01000001, 0xd82070e4, 0x17c07c1f, 0x1a40001f, 0x10006220,
211 	0x1a80001f, 0x10006274, 0xc24027a0, 0x17c07c1f, 0x89400005, 0xfffffff7,
212 	0xe8208000, 0x10006f0c, 0x00000000, 0xe8208000, 0x10006b3c, 0x00000000,
213 	0xe8208000, 0x100063e0, 0x00000008, 0x1910001f, 0x10006610, 0x81079001,
214 	0xd8207844, 0x17c07c1f, 0x81021401, 0xd82074e4, 0x17c07c1f, 0x1a10001f,
215 	0x10006918, 0x81022001, 0xb1062081, 0xb900008c, 0x01000001, 0xd82074e4,
216 	0x17c07c1f, 0x1a40001f, 0x100062a0, 0x1280041f, 0xc2402b20, 0x17c07c1f,
217 	0x89400005, 0xffffffef, 0xe8208000, 0x10006f10, 0x00000000, 0xe8208000,
218 	0x10006b40, 0x00000000, 0xe8208000, 0x100063e0, 0x00000010, 0x81029401,
219 	0xd8207844, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8102a001, 0xb106a081,
220 	0xb900008c, 0x01000001, 0xd8207844, 0x17c07c1f, 0x1a40001f, 0x100062a4,
221 	0x1290841f, 0xc2402b20, 0x17c07c1f, 0x89400005, 0xffffffdf, 0xe8208000,
222 	0x10006f14, 0x00000000, 0xe8208000, 0x10006b44, 0x00000000, 0xe8208000,
223 	0x100063e0, 0x00000020, 0x81031401, 0xd8207b04, 0x17c07c1f, 0x1a10001f,
224 	0x10006918, 0x81032001, 0xb1072081, 0xb900008c, 0x01000001, 0xd8207b04,
225 	0x17c07c1f, 0x89400005, 0xffffffbf, 0xe8208000, 0x10006f18, 0x00000000,
226 	0xe8208000, 0x10006b48, 0x00000000, 0xe8208000, 0x100063e0, 0x00000040,
227 	0x81039401, 0xd8207dc4, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8103a001,
228 	0xb107a081, 0xb900008c, 0x01000001, 0xd8207dc4, 0x17c07c1f, 0x89400005,
229 	0xffffff7f, 0xe8208000, 0x10006f1c, 0x00000000, 0xe8208000, 0x10006b4c,
230 	0x00000000, 0xe8208000, 0x100063e0, 0x00000080, 0xd0004220, 0x17c07c1f,
231 	0xe8208000, 0x10006600, 0x00000000, 0x1ac0001f, 0x55aa55aa, 0x1940001f,
232 	0xaa55aa55, 0x1b80001f, 0x00001000, 0xf0000000, 0x17c07c1f
233 };
234 
235 static const struct pcm_desc mcdi_pcm = {
236 	.version = "pcm_mcdi_mt8173_20151203_v6",
237 	.base = mcdi_binary,
238 	.size = 1019,
239 	.sess = 2,
240 	.replace = 0,
241 };
242 
243 static struct pwr_ctrl mcdi_ctrl = {
244 	.wake_src = WAKE_SRC_FOR_MCDI,
245 	.wake_src_md32 = 0,
246 	.wfi_op = WFI_OP_OR,
247 	.mcusys_idle_mask = 1,
248 	.ca7top_idle_mask = 1,
249 	.ca15top_idle_mask = 1,
250 	.disp_req_mask = 1,
251 	.mfg_req_mask = 1,
252 	.md32_req_mask = 1,
253 };
254 
255 static const struct spm_lp_scen spm_mcdi = {
256 	.pcmdesc = &mcdi_pcm,
257 	.pwrctrl = &mcdi_ctrl,
258 };
259 
260 void spm_mcdi_cpu_wake_up_event(int wake_up_event, int disable_dormant_power)
261 {
262 	if (((mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) & 0x1) == 1)
263 	    && ((mmio_read_32(SPM_CLK_CON) & CC_DISABLE_DORM_PWR) == 0)) {
264 		/* MCDI is offload? */
265 		INFO("%s: SPM_SLEEP_CPU_WAKEUP_EVENT:%x, SPM_CLK_CON %x",
266 			__func__, mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT),
267 			mmio_read_32(SPM_CLK_CON));
268 		return;
269 	}
270 	/* Inform SPM that CPU wants to program CPU_WAKEUP_EVENT and
271 	 * DISABLE_CPU_DROM */
272 	mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_HANDSHAKE_SYNC);
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 	/* Wait SPM's response, can't use sleep api */
277 	while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_HANDSHAKE_ACK)
278 		;
279 
280 	if (disable_dormant_power) {
281 		mmio_setbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
282 		while (mmio_read_32(SPM_CLK_CON) !=
283 			(mmio_read_32(SPM_CLK_CON) | CC_DISABLE_DORM_PWR))
284 			;
285 
286 	} else {
287 		mmio_clrbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
288 		while (mmio_read_32(SPM_CLK_CON) !=
289 			(mmio_read_32(SPM_CLK_CON) & ~CC_DISABLE_DORM_PWR))
290 			;
291 	}
292 
293 	mmio_write_32(SPM_SLEEP_CPU_WAKEUP_EVENT, wake_up_event);
294 
295 	while (mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) != wake_up_event)
296 		;
297 
298 	/* Inform SPM to see updated setting */
299 	mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_UPDATE_INFORM);
300 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
301 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
302 
303 	while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_CKECK_DONE)
304 		;
305 	/* END OF sequence */
306 
307 	mmio_write_32(SPM_PCM_REG_DATA_INI, 0x0);
308 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
309 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
310 }
311 
312 void spm_mcdi_wakeup_all_cores(void)
313 {
314 	if (is_mcdi_ready() == 0)
315 		return;
316 
317 	spm_mcdi_cpu_wake_up_event(1, 1);
318 	while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_ALL_CORE_AWAKE)
319 		;
320 	spm_mcdi_cpu_wake_up_event(1, 0);
321 	while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_OFFLOADED)
322 		;
323 
324 	spm_clean_after_wakeup();
325 	clear_all_ready();
326 }
327 
328 static void spm_mcdi_wfi_sel_enter(unsigned long mpidr)
329 {
330 	int core_id_val = mpidr & MPIDR_CPU_MASK;
331 	int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
332 
333 	/* SPM WFI Select by core number */
334 	if (cluster_id) {
335 		switch (core_id_val) {
336 		case 0:
337 			mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 1);
338 			mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 1);
339 			break;
340 		case 1:
341 			mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 1);
342 			mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 1);
343 			break;
344 		case 2:
345 			mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 1);
346 			mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 1);
347 			break;
348 		case 3:
349 			mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 1);
350 			mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 1);
351 			break;
352 		default:
353 			break;
354 		}
355 	} else {
356 		switch (core_id_val) {
357 		case 0:
358 			mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 1);
359 			mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 1);
360 			break;
361 		case 1:
362 			mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 1);
363 			mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 1);
364 			break;
365 		case 2:
366 			mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 1);
367 			mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 1);
368 			break;
369 		case 3:
370 			mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 1);
371 			mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 1);
372 			break;
373 		default:
374 			break;
375 		}
376 	}
377 }
378 
379 static void spm_mcdi_wfi_sel_leave(unsigned long mpidr)
380 {
381 	int core_id_val = mpidr & MPIDR_CPU_MASK;
382 	int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
383 
384 	/* SPM WFI Select by core number */
385 	if (cluster_id) {
386 		switch (core_id_val) {
387 		case 0:
388 			mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 0);
389 			mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 0);
390 			break;
391 		case 1:
392 			mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 0);
393 			mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 0);
394 			break;
395 		case 2:
396 			mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 0);
397 			mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 0);
398 			break;
399 		case 3:
400 			mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 0);
401 			mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 0);
402 			break;
403 		default:
404 			break;
405 		}
406 	} else {
407 		switch (core_id_val) {
408 		case 0:
409 			mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 0);
410 			mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 0);
411 			break;
412 		case 1:
413 			mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 0);
414 			mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 0);
415 			break;
416 		case 2:
417 			mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 0);
418 			mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 0);
419 			break;
420 		case 3:
421 			mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 0);
422 			mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 0);
423 			break;
424 		default:
425 			break;
426 		}
427 	}
428 }
429 
430 static void spm_mcdi_set_cputop_pwrctrl_for_cluster_off(unsigned long mpidr)
431 {
432 	unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
433 	unsigned long cpu_id = mpidr & MPIDR_CPU_MASK;
434 	unsigned int pwr_status, shift, i, flag = 0;
435 
436 	pwr_status = mmio_read_32(SPM_PWR_STATUS) |
437 				 mmio_read_32(SPM_PWR_STATUS_2ND);
438 
439 	if (cluster_id) {
440 		for (i = 0; i < PLATFORM_CLUSTER1_CORE_COUNT; i++) {
441 			if (i == cpu_id)
442 				continue;
443 			shift = i + PCM_MCDI_CA72_PWRSTA_SHIFT;
444 			flag |= (pwr_status & (1 << shift)) >> shift;
445 		}
446 		if (!flag)
447 			mmio_setbits_32(SPM_PCM_RESERVE,
448 					PCM_MCDI_CA72_CPUTOP_PWRCTL);
449 	} else {
450 		for (i = 0; i < PLATFORM_CLUSTER0_CORE_COUNT; i++) {
451 			if (i == cpu_id)
452 				continue;
453 			shift = i + PCM_MCDI_CA53_PWRSTA_SHIFT;
454 			flag |= (pwr_status & (1 << shift)) >> shift;
455 		}
456 		if (!flag)
457 			mmio_setbits_32(SPM_PCM_RESERVE,
458 					PCM_MCDI_CA53_CPUTOP_PWRCTL);
459 	}
460 }
461 
462 static void spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(unsigned long mpidr)
463 {
464 	unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
465 
466 	if (cluster_id)
467 		mmio_clrbits_32(SPM_PCM_RESERVE,
468 				PCM_MCDI_CA72_CPUTOP_PWRCTL);
469 	else
470 		mmio_clrbits_32(SPM_PCM_RESERVE,
471 				PCM_MCDI_CA53_CPUTOP_PWRCTL);
472 }
473 
474 void spm_mcdi_prepare_for_mtcmos(void)
475 {
476 	const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
477 	struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
478 
479 	if (is_mcdi_ready() == 0) {
480 		if (is_hotplug_ready() == 1)
481 			spm_clear_hotplug();
482 		set_pwrctrl_pcm_flags(pwrctrl, 0);
483 		spm_reset_and_init_pcm();
484 		spm_kick_im_to_fetch(pcmdesc);
485 		spm_set_power_control(pwrctrl);
486 		spm_set_wakeup_event(pwrctrl);
487 		spm_kick_pcm_to_run(pwrctrl);
488 		set_mcdi_ready();
489 	}
490 }
491 
492 void spm_mcdi_prepare_for_off_state(unsigned long mpidr, unsigned int afflvl)
493 {
494 	const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
495 	struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
496 
497 	spm_lock_get();
498 	if (is_mcdi_ready() == 0) {
499 		if (is_hotplug_ready() == 1)
500 			spm_clear_hotplug();
501 		set_pwrctrl_pcm_flags(pwrctrl, 0);
502 		spm_reset_and_init_pcm();
503 		spm_kick_im_to_fetch(pcmdesc);
504 		spm_set_power_control(pwrctrl);
505 		spm_set_wakeup_event(pwrctrl);
506 		spm_kick_pcm_to_run(pwrctrl);
507 		set_mcdi_ready();
508 	}
509 	spm_mcdi_wfi_sel_enter(mpidr);
510 	if (afflvl == MPIDR_AFFLVL1)
511 		spm_mcdi_set_cputop_pwrctrl_for_cluster_off(mpidr);
512 	spm_lock_release();
513 }
514 
515 void spm_mcdi_finish_for_on_state(unsigned long mpidr, unsigned int afflvl)
516 {
517 	unsigned long linear_id = platform_get_core_pos(mpidr);
518 
519 	spm_lock_get();
520 	spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(mpidr);
521 	spm_mcdi_wfi_sel_leave(mpidr);
522 	mmio_write_32(SPM_PCM_SW_INT_CLEAR, (0x1 << linear_id));
523 	spm_lock_release();
524 }
525