xref: /rk3399_ARM-atf/plat/mediatek/mt8173/drivers/spm/spm_mcdi.c (revision 8e53ec53b6381fef325539cb13d6164dbc6c308e)
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	(WAKE_SRC_SYSPWREQ | WAKE_SRC_CPU_IRQ)
47 #define PCM_MCDI_HANDSHAKE_SYNC	0xbeefbeef
48 #define PCM_MCDI_HANDSHAKE_ACK	0xdeaddead
49 #define PCM_MCDI_UPDATE_INFORM	0xabcdabcd
50 #define PCM_MCDI_CKECK_DONE	0x12345678
51 #define PCM_MCDI_ALL_CORE_AWAKE	0x0
52 #define PCM_MCDI_OFFLOADED	0xaa55aa55
53 #define PCM_MCDI_CA72_CPUTOP_PWRCTL	(0x1 << 16)
54 #define PCM_MCDI_CA53_CPUTOP_PWRCTL	(0x1 << 17)
55 #define PCM_MCDI_CA72_PWRSTA_SHIFT	16
56 #define PCM_MCDI_CA53_PWRSTA_SHIFT	9
57 
58 static const unsigned int mcdi_binary[] = {
59 	0x1a10001f, 0x10006918, 0x81002001, 0xb100a081, 0xb1012081, 0xb101a081,
60 	0xb1042081, 0xb104a081, 0xb1052081, 0xb105a081, 0xb1003081, 0xd8200984,
61 	0x17c07c1f, 0xe2e00036, 0xe2e0003e, 0x1910001f, 0x1000660c, 0x81041001,
62 	0x1a10001f, 0x10006610, 0x82042001, 0x81002004, 0xd82001e4, 0x17c07c1f,
63 	0xe2e0003c, 0xe8208000, 0x10006244, 0x00000000, 0x1910001f, 0x10006244,
64 	0x81041001, 0xd8000384, 0x17c07c1f, 0x1b80001f, 0x20000030, 0xe2e0007c,
65 	0x1b80001f, 0x20000003, 0xe2e0005c, 0xe2e0004c, 0xe2e0004d, 0x1900001f,
66 	0x10001250, 0x1a10001f, 0x10001250, 0x8a000008, 0xfffffffb, 0xe1000008,
67 	0x1900001f, 0x10001258, 0x1a10001f, 0x10001258, 0x81012001, 0xd8000604,
68 	0x17c07c1f, 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220, 0x8a000008,
69 	0xdfffffff, 0xe1000008, 0x1900001f, 0x10001228, 0x1a10001f, 0x10001228,
70 	0x810ea001, 0xd80007c4, 0x17c07c1f, 0x1900001f, 0x1020002c, 0x1a10001f,
71 	0x1020002c, 0x8a000008, 0xffffffef, 0xe1000008, 0xf0000000, 0x17c07c1f,
72 	0x1900001f, 0x1020002c, 0x1a10001f, 0x1020002c, 0xaa000008, 0x00000010,
73 	0xe1000008, 0x1910001f, 0x10006720, 0x820c1001, 0xd8200aa8, 0x17c07c1f,
74 	0x1900001f, 0x10001250, 0x1a10001f, 0x10001250, 0xa2110408, 0xe1000008,
75 	0x1900001f, 0x10001258, 0x1a10001f, 0x10001258, 0x81012001, 0xd8200c04,
76 	0x17c07c1f, 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220, 0xa21e8408,
77 	0xe1000008, 0x1900001f, 0x10001228, 0x1a10001f, 0x10001228, 0x810ea001,
78 	0xd8200da4, 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f, 0xe8208000,
79 	0x10006244, 0x00000001, 0x1910001f, 0x10006244, 0x81041001, 0xd8200f44,
80 	0x17c07c1f, 0xe2e0002e, 0xe2e0003e, 0xe2e0003a, 0xe2e00032, 0x1910001f,
81 	0x1000660c, 0x81041001, 0x1a10001f, 0x10006610, 0x82042001, 0xa1002004,
82 	0xd8001064, 0x17c07c1f, 0x1910001f, 0x10006b04, 0x01000404, 0x1a00001f,
83 	0x10006b04, 0xe2000004, 0xf0000000, 0x17c07c1f, 0x1212841f, 0xe2e00036,
84 	0xe2e0003e, 0x1380201f, 0xe2e0003c, 0xe2a00000, 0x1b80001f, 0x20000080,
85 	0xe2e0007c, 0x1b80001f, 0x20000003, 0xe2e0005c, 0xe2e0004c, 0xe2e0004d,
86 	0xf0000000, 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f, 0xe2a00001,
87 	0x1b80001f, 0x20000080, 0xe2e0002e, 0xe2e0003e, 0xe2e0003a, 0xe2e00032,
88 	0xf0000000, 0x17c07c1f, 0x1212841f, 0xe2e00026, 0xe2e0002e, 0x1380201f,
89 	0x1a00001f, 0x100062b4, 0x1910001f, 0x100062b4, 0x81322804, 0xe2000004,
90 	0x81202804, 0xe2000004, 0x1b80001f, 0x20000034, 0x1910001f, 0x100062b4,
91 	0x81142804, 0xd80017c4, 0x17c07c1f, 0xe2e0000e, 0xe2e0000c, 0xe2e0000d,
92 	0xf0000000, 0x17c07c1f, 0xe2e0002d, 0x1a00001f, 0x100062b4, 0x1910001f,
93 	0x100062b4, 0xa1002804, 0xe2000004, 0xa1122804, 0xe2000004, 0x1b80001f,
94 	0x20000080, 0x1910001f, 0x100062b4, 0x81142804, 0xd8201a64, 0x17c07c1f,
95 	0xe2e0002f, 0xe2e0002b, 0xe2e00023, 0x1380201f, 0xe2e00022, 0xf0000000,
96 	0x17c07c1f, 0x1900001f, 0x1020020c, 0x1a10001f, 0x1020020c, 0xaa000008,
97 	0x00000001, 0xe1000008, 0x1910001f, 0x10006720, 0x820c9001, 0xd8201cc8,
98 	0x17c07c1f, 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220, 0xa21f0408,
99 	0xe1000008, 0x1900001f, 0x10001228, 0x1a10001f, 0x10001228, 0x810f2001,
100 	0xd8201e24, 0x17c07c1f, 0xe2e0006d, 0xe2e0002d, 0x1a00001f, 0x100062b8,
101 	0x1910001f, 0x100062b8, 0xa9000004, 0x00000001, 0xe2000004, 0x1910001f,
102 	0x100062b8, 0x81041001, 0xd8202024, 0x17c07c1f, 0xe2e0002c, 0xe2e0003c,
103 	0xe2e0003e, 0xe2e0003a, 0xe2e00032, 0x1910001f, 0x1000660c, 0x81079001,
104 	0x1a10001f, 0x10006610, 0x8207a001, 0xa1002004, 0xd8002164, 0x17c07c1f,
105 	0x1900001f, 0x10006404, 0x1a10001f, 0x10006404, 0xa2168408, 0xe1000008,
106 	0xf0000000, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81022001, 0xb102a081,
107 	0xb1062081, 0xb106a081, 0xb1003081, 0xd8202ba4, 0x17c07c1f, 0x1900001f,
108 	0x10006404, 0x1a10001f, 0x10006404, 0x8a000008, 0x0000dfff, 0xe1000008,
109 	0xe2e00036, 0xe2e0003e, 0x1910001f, 0x1000660c, 0x81079001, 0x1a10001f,
110 	0x10006610, 0x8207a001, 0x81002004, 0xd82025c4, 0x17c07c1f, 0xe2e0002e,
111 	0x1a00001f, 0x100062b8, 0x1910001f, 0x100062b8, 0x89000004, 0x0000fffe,
112 	0xe2000004, 0x1910001f, 0x100062b8, 0x81041001, 0xd80027e4, 0x17c07c1f,
113 	0xe2e0006e, 0xe2e0004e, 0xe2e0004c, 0xe2e0004d, 0x1900001f, 0x10001220,
114 	0x1a10001f, 0x10001220, 0x8a000008, 0xbfffffff, 0xe1000008, 0x1900001f,
115 	0x10001228, 0x1a10001f, 0x10001228, 0x810f2001, 0xd80029e4, 0x17c07c1f,
116 	0x1900001f, 0x1020020c, 0x1a10001f, 0x1020020c, 0x8a000008, 0xfffffffe,
117 	0xe1000008, 0xf0000000, 0x17c07c1f, 0x18c0001f, 0x10006b6c, 0x1910001f,
118 	0x10006b6c, 0xa1002804, 0xe0c00004, 0xf0000000, 0x17c07c1f, 0x17c07c1f,
119 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
120 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
121 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
122 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
123 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
124 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
125 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
126 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
127 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
128 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
129 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
130 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
131 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
132 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
133 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
134 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
135 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
136 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
137 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
138 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
139 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
140 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
141 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
142 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
143 	0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f, 0x17c07c1f,
144 	0x17c07c1f, 0x17c07c1f, 0x1840001f, 0x00000001, 0x11407c1f, 0xe8208000,
145 	0x10006b6c, 0xa0000000, 0xe8208000, 0x10006310, 0x0b160008, 0x1900001f,
146 	0x000f7bde, 0x1a00001f, 0x10200268, 0xe2000004, 0xe8208000, 0x10006600,
147 	0x00000000, 0xc2802be0, 0x1280041f, 0xe8208000, 0x10006b04, 0x00000000,
148 	0x1b00001f, 0x21000001, 0x1b80001f, 0xd0010000, 0xc2802be0, 0x1290841f,
149 	0x69200006, 0xbeefbeef, 0xd82047c4, 0x17c07c1f, 0xc2802be0, 0x1291041f,
150 	0x1910001f, 0x10006358, 0x810b1001, 0xd8004444, 0x17c07c1f, 0x1980001f,
151 	0xdeaddead, 0x69200006, 0xabcdabcd, 0xd8204524, 0x17c07c1f, 0xc2802be0,
152 	0x1291841f, 0x88900001, 0x10006814, 0x1910001f, 0x10006400, 0x81271002,
153 	0x1880001f, 0x10006600, 0xe0800004, 0x1910001f, 0x10006358, 0x810b1001,
154 	0xd80046e4, 0x17c07c1f, 0x1980001f, 0x12345678, 0x60a07c05, 0x89100002,
155 	0x10006600, 0x80801001, 0xd8007742, 0x17c07c1f, 0xc2802be0, 0x1292041f,
156 	0x1a10001f, 0x10006720, 0x82002001, 0x82201408, 0xd8204a68, 0x17c07c1f,
157 	0x1a40001f, 0x10006200, 0x1a80001f, 0x1000625c, 0xc2401480, 0x17c07c1f,
158 	0xa1400405, 0xc2802be0, 0x1292841f, 0x1a10001f, 0x10006720, 0x8200a001,
159 	0x82209408, 0xd8204c48, 0x17c07c1f, 0x1a40001f, 0x10006218, 0x1a80001f,
160 	0x10006264, 0xc2401480, 0x17c07c1f, 0xa1508405, 0xc2802be0, 0x1293041f,
161 	0x1a10001f, 0x10006720, 0x82012001, 0x82211408, 0xd8204e28, 0x17c07c1f,
162 	0x1a40001f, 0x1000621c, 0x1a80001f, 0x1000626c, 0xc2401480, 0x17c07c1f,
163 	0xa1510405, 0x1a10001f, 0x10006720, 0x8201a001, 0x82219408, 0xd8204fc8,
164 	0x17c07c1f, 0x1a40001f, 0x10006220, 0x1a80001f, 0x10006274, 0xc2401480,
165 	0x17c07c1f, 0xa1518405, 0x1a10001f, 0x10006720, 0x82022001, 0x82221408,
166 	0xd8205148, 0x17c07c1f, 0x1a40001f, 0x100062a0, 0x1280041f, 0xc2401900,
167 	0x17c07c1f, 0xa1520405, 0x1a10001f, 0x10006720, 0x8202a001, 0x82229408,
168 	0xd82052c8, 0x17c07c1f, 0x1a40001f, 0x100062a4, 0x1290841f, 0xc2401900,
169 	0x17c07c1f, 0xa1528405, 0x1a10001f, 0x10006720, 0x82032001, 0x82231408,
170 	0xd82053a8, 0x17c07c1f, 0xa1530405, 0x1a10001f, 0x10006720, 0x8203a001,
171 	0x82239408, 0xd8205488, 0x17c07c1f, 0xa1538405, 0x1a10001f, 0x10006b00,
172 	0x8108a001, 0xd8205864, 0x17c07c1f, 0x1a10001f, 0x10006610, 0x8104a001,
173 	0xb1052081, 0xb105a081, 0xb1062081, 0xd8005744, 0x17c07c1f, 0x1a10001f,
174 	0x10006610, 0x81042001, 0xd8205744, 0x17c07c1f, 0x1a40001f, 0x10006208,
175 	0xc24009c0, 0x17c07c1f, 0x1910001f, 0x10006610, 0x81041001, 0xd8005864,
176 	0x17c07c1f, 0x1a40001f, 0x10006208, 0xc2400000, 0x17c07c1f, 0x1a10001f,
177 	0x10006b00, 0x81082001, 0xd8205ae4, 0x17c07c1f, 0x1a10001f, 0x10006610,
178 	0x81082001, 0xb108a081, 0xd8005ae4, 0x17c07c1f, 0x1a10001f, 0x10006610,
179 	0x8107a001, 0xd8205ae4, 0x17c07c1f, 0x1a40001f, 0x100062b0, 0xc2401be0,
180 	0x17c07c1f, 0x1b80001f, 0x20000208, 0xd82076cc, 0x17c07c1f, 0x1910001f,
181 	0x10006610, 0x81079001, 0xd8005c84, 0x17c07c1f, 0x1a40001f, 0x100062b0,
182 	0xc2402380, 0x17c07c1f, 0x81001401, 0xd8206004, 0x17c07c1f, 0x1a10001f,
183 	0x10006918, 0x81002001, 0xb1042081, 0xb1003081, 0xb10c3081, 0xd8206004,
184 	0x17c07c1f, 0x1a40001f, 0x10006200, 0x1a80001f, 0x1000625c, 0xc2401280,
185 	0x17c07c1f, 0x89400005, 0xfffffffe, 0xe8208000, 0x10006f00, 0x00000000,
186 	0xe8208000, 0x10006b30, 0x00000000, 0xe8208000, 0x100063e0, 0x00000001,
187 	0x81009401, 0xd8206364, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8100a001,
188 	0xb104a081, 0xb1003081, 0xd8206364, 0x17c07c1f, 0x1a40001f, 0x10006218,
189 	0x1a80001f, 0x10006264, 0xc2401280, 0x17c07c1f, 0x89400005, 0xfffffffd,
190 	0xe8208000, 0x10006f04, 0x00000000, 0xe8208000, 0x10006b34, 0x00000000,
191 	0xe8208000, 0x100063e0, 0x00000002, 0x81011401, 0xd82066c4, 0x17c07c1f,
192 	0x1a10001f, 0x10006918, 0x81012001, 0xb1052081, 0xb1003081, 0xd82066c4,
193 	0x17c07c1f, 0x1a40001f, 0x1000621c, 0x1a80001f, 0x1000626c, 0xc2401280,
194 	0x17c07c1f, 0x89400005, 0xfffffffb, 0xe8208000, 0x10006f08, 0x00000000,
195 	0xe8208000, 0x10006b38, 0x00000000, 0xe8208000, 0x100063e0, 0x00000004,
196 	0x81019401, 0xd8206a24, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x8101a001,
197 	0xb105a081, 0xb1003081, 0xd8206a24, 0x17c07c1f, 0x1a40001f, 0x10006220,
198 	0x1a80001f, 0x10006274, 0xc2401280, 0x17c07c1f, 0x89400005, 0xfffffff7,
199 	0xe8208000, 0x10006f0c, 0x00000000, 0xe8208000, 0x10006b3c, 0x00000000,
200 	0xe8208000, 0x100063e0, 0x00000008, 0x1910001f, 0x10006610, 0x81079001,
201 	0xd8207144, 0x17c07c1f, 0x81021401, 0xd8206e04, 0x17c07c1f, 0x1a10001f,
202 	0x10006918, 0x81022001, 0xb1062081, 0xb1003081, 0xd8206e04, 0x17c07c1f,
203 	0x1a40001f, 0x100062a0, 0x1280041f, 0xc2401600, 0x17c07c1f, 0x89400005,
204 	0xffffffef, 0xe8208000, 0x10006f10, 0x00000000, 0xe8208000, 0x10006b40,
205 	0x00000000, 0xe8208000, 0x100063e0, 0x00000010, 0x81029401, 0xd8207144,
206 	0x17c07c1f, 0x1a10001f, 0x10006918, 0x8102a001, 0xb106a081, 0xb1003081,
207 	0xd8207144, 0x17c07c1f, 0x1a40001f, 0x100062a4, 0x1290841f, 0xc2401600,
208 	0x17c07c1f, 0x89400005, 0xffffffdf, 0xe8208000, 0x10006f14, 0x00000000,
209 	0xe8208000, 0x10006b44, 0x00000000, 0xe8208000, 0x100063e0, 0x00000020,
210 	0x81031401, 0xd82073e4, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81032001,
211 	0xb1072081, 0xb1003081, 0xd82073e4, 0x17c07c1f, 0x89400005, 0xffffffbf,
212 	0xe8208000, 0x10006f18, 0x00000000, 0xe8208000, 0x10006b48, 0x00000000,
213 	0xe8208000, 0x100063e0, 0x00000040, 0x81039401, 0xd8207684, 0x17c07c1f,
214 	0x1a10001f, 0x10006918, 0x8103a001, 0xb107a081, 0xb1003081, 0xd8207684,
215 	0x17c07c1f, 0x89400005, 0xffffff7f, 0xe8208000, 0x10006f1c, 0x00000000,
216 	0xe8208000, 0x10006b4c, 0x00000000, 0xe8208000, 0x100063e0, 0x00000080,
217 	0xc2802be0, 0x1293841f, 0xd00042c0, 0x17c07c1f, 0xc2802be0, 0x1294041f,
218 	0xe8208000, 0x10006600, 0x00000000, 0x1ac0001f, 0x55aa55aa, 0x1940001f,
219 	0xaa55aa55, 0xc2802be0, 0x1294841f, 0x1b80001f, 0x00001000, 0xf0000000,
220 	0x17c07c1f
221 };
222 
223 static const struct pcm_desc mcdi_pcm = {
224 	.version = "pcm_mcdi_mt8173_20150901_v1",
225 	.base = mcdi_binary,
226 	.size = 967,
227 	.sess = 2,
228 	.replace = 0,
229 };
230 
231 static struct pwr_ctrl mcdi_ctrl = {
232 	.wake_src = WAKE_SRC_FOR_MCDI,
233 	.wake_src_md32 = 0,
234 	.wfi_op = WFI_OP_OR,
235 	.mcusys_idle_mask = 1,
236 	.ca7top_idle_mask = 1,
237 	.ca15top_idle_mask = 1,
238 	.disp_req_mask = 1,
239 	.mfg_req_mask = 1,
240 	.md32_req_mask = 1,
241 };
242 
243 static const struct spm_lp_scen spm_mcdi = {
244 	.pcmdesc = &mcdi_pcm,
245 	.pwrctrl = &mcdi_ctrl,
246 };
247 
248 void spm_mcdi_cpu_wake_up_event(int wake_up_event, int disable_dormant_power)
249 {
250 	if (((mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) & 0x1) == 1)
251 	    && ((mmio_read_32(SPM_CLK_CON) & CC_DISABLE_DORM_PWR) == 0)) {
252 		/* MCDI is offload? */
253 		INFO("%s: SPM_SLEEP_CPU_WAKEUP_EVENT:%x, SPM_CLK_CON %x",
254 			__func__, mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT),
255 			mmio_read_32(SPM_CLK_CON));
256 		return;
257 	}
258 	/* Inform SPM that CPU wants to program CPU_WAKEUP_EVENT and
259 	 * DISABLE_CPU_DROM */
260 	mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_HANDSHAKE_SYNC);
261 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
262 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
263 
264 	/* Wait SPM's response, can't use sleep api */
265 	while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_HANDSHAKE_ACK)
266 		;
267 
268 	if (disable_dormant_power) {
269 		mmio_setbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
270 		while (mmio_read_32(SPM_CLK_CON) !=
271 			(mmio_read_32(SPM_CLK_CON) | CC_DISABLE_DORM_PWR))
272 			;
273 
274 	} else {
275 		mmio_clrbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
276 		while (mmio_read_32(SPM_CLK_CON) !=
277 			(mmio_read_32(SPM_CLK_CON) & ~CC_DISABLE_DORM_PWR))
278 			;
279 	}
280 
281 	mmio_write_32(SPM_SLEEP_CPU_WAKEUP_EVENT, wake_up_event);
282 
283 	while (mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) != wake_up_event)
284 		;
285 
286 	/* Inform SPM to see updated setting */
287 	mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_UPDATE_INFORM);
288 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
289 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
290 
291 	while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_CKECK_DONE)
292 		;
293 	/* END OF sequence */
294 
295 	mmio_write_32(SPM_PCM_REG_DATA_INI, 0x0);
296 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
297 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
298 }
299 
300 void spm_mcdi_wakeup_all_cores(void)
301 {
302 	if (is_mcdi_ready() == 0)
303 		return;
304 
305 	spm_mcdi_cpu_wake_up_event(1, 1);
306 	while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_ALL_CORE_AWAKE)
307 		;
308 	spm_mcdi_cpu_wake_up_event(1, 0);
309 	while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_OFFLOADED)
310 		;
311 
312 	spm_clean_after_wakeup();
313 	clear_all_ready();
314 }
315 
316 static void spm_mcdi_wfi_sel_enter(unsigned long mpidr)
317 {
318 	int core_id_val = mpidr & MPIDR_CPU_MASK;
319 	int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
320 
321 	/* SPM WFI Select by core number */
322 	if (cluster_id) {
323 		switch (core_id_val) {
324 		case 0:
325 			mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 1);
326 			mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 1);
327 			break;
328 		case 1:
329 			mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 1);
330 			mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 1);
331 			break;
332 		case 2:
333 			mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 1);
334 			mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 1);
335 			break;
336 		case 3:
337 			mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 1);
338 			mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 1);
339 			break;
340 		default:
341 			break;
342 		}
343 	} else {
344 		switch (core_id_val) {
345 		case 0:
346 			mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 1);
347 			mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 1);
348 			break;
349 		case 1:
350 			mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 1);
351 			mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 1);
352 			break;
353 		case 2:
354 			mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 1);
355 			mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 1);
356 			break;
357 		case 3:
358 			mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 1);
359 			mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 1);
360 			break;
361 		default:
362 			break;
363 		}
364 	}
365 }
366 
367 static void spm_mcdi_wfi_sel_leave(unsigned long mpidr)
368 {
369 	int core_id_val = mpidr & MPIDR_CPU_MASK;
370 	int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
371 
372 	/* SPM WFI Select by core number */
373 	if (cluster_id) {
374 		switch (core_id_val) {
375 		case 0:
376 			mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 0);
377 			mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 0);
378 			break;
379 		case 1:
380 			mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 0);
381 			mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 0);
382 			break;
383 		case 2:
384 			mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 0);
385 			mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 0);
386 			break;
387 		case 3:
388 			mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 0);
389 			mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 0);
390 			break;
391 		default:
392 			break;
393 		}
394 	} else {
395 		switch (core_id_val) {
396 		case 0:
397 			mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 0);
398 			mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 0);
399 			break;
400 		case 1:
401 			mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 0);
402 			mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 0);
403 			break;
404 		case 2:
405 			mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 0);
406 			mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 0);
407 			break;
408 		case 3:
409 			mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 0);
410 			mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 0);
411 			break;
412 		default:
413 			break;
414 		}
415 	}
416 }
417 
418 static void spm_mcdi_set_cputop_pwrctrl_for_cluster_off(unsigned long mpidr)
419 {
420 	unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
421 	unsigned long cpu_id = mpidr & MPIDR_CPU_MASK;
422 	unsigned int pwr_status, shift, i, flag = 0;
423 
424 	pwr_status = mmio_read_32(SPM_PWR_STATUS) |
425 				 mmio_read_32(SPM_PWR_STATUS_2ND);
426 
427 	if (cluster_id) {
428 		for (i = 0; i < PLATFORM_CLUSTER1_CORE_COUNT; i++) {
429 			if (i == cpu_id)
430 				continue;
431 			shift = i + PCM_MCDI_CA72_PWRSTA_SHIFT;
432 			flag |= (pwr_status & (1 << shift)) >> shift;
433 		}
434 		if (!flag)
435 			mmio_setbits_32(SPM_PCM_RESERVE,
436 					PCM_MCDI_CA72_CPUTOP_PWRCTL);
437 	} else {
438 		for (i = 0; i < PLATFORM_CLUSTER0_CORE_COUNT; i++) {
439 			if (i == cpu_id)
440 				continue;
441 			shift = i + PCM_MCDI_CA53_PWRSTA_SHIFT;
442 			flag |= (pwr_status & (1 << shift)) >> shift;
443 		}
444 		if (!flag)
445 			mmio_setbits_32(SPM_PCM_RESERVE,
446 					PCM_MCDI_CA53_CPUTOP_PWRCTL);
447 	}
448 }
449 
450 static void spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(unsigned long mpidr)
451 {
452 	unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
453 
454 	if (cluster_id)
455 		mmio_clrbits_32(SPM_PCM_RESERVE,
456 				PCM_MCDI_CA72_CPUTOP_PWRCTL);
457 	else
458 		mmio_clrbits_32(SPM_PCM_RESERVE,
459 				PCM_MCDI_CA53_CPUTOP_PWRCTL);
460 }
461 
462 void spm_mcdi_prepare_for_off_state(unsigned long mpidr, unsigned int afflvl)
463 {
464 	const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
465 	struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
466 
467 	spm_lock_get();
468 	if (is_mcdi_ready() == 0) {
469 		if (is_hotplug_ready() == 1)
470 			spm_clear_hotplug();
471 		set_pwrctrl_pcm_flags(pwrctrl, 0);
472 		spm_reset_and_init_pcm();
473 		spm_kick_im_to_fetch(pcmdesc);
474 		spm_set_power_control(pwrctrl);
475 		spm_set_wakeup_event(pwrctrl);
476 		spm_kick_pcm_to_run(pwrctrl);
477 		set_mcdi_ready();
478 	}
479 	spm_mcdi_wfi_sel_enter(mpidr);
480 	if (afflvl == MPIDR_AFFLVL1)
481 		spm_mcdi_set_cputop_pwrctrl_for_cluster_off(mpidr);
482 	spm_lock_release();
483 }
484 
485 void spm_mcdi_finish_for_on_state(unsigned long mpidr, unsigned int afflvl)
486 {
487 	unsigned long linear_id = platform_get_core_pos(mpidr);
488 
489 	spm_lock_get();
490 	spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(mpidr);
491 	spm_mcdi_wfi_sel_leave(mpidr);
492 	mmio_write_32(SPM_PCM_SW_INT_CLEAR, (0x1 << linear_id));
493 	spm_lock_release();
494 }
495