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