xref: /rk3399_ARM-atf/plat/mediatek/mt8173/drivers/spm/spm_mcdi.c (revision 1a1ff8b96282dd86705b3f697b1445916048a8e7)
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, 0x10006b04, 0x1890001f, 0x10006b6c, 0x1a40001f, 0x10006210,
60 	0x81002001, 0xd8200184, 0x17c07c1f, 0xa0900402, 0xc24012a0, 0x17c07c1f,
61 	0x81052001, 0xd8200244, 0x17c07c1f, 0x80b00402, 0xc2401760, 0x17c07c1f,
62 	0x1a40001f, 0x10006230, 0x8100a001, 0xd8200344, 0x17c07c1f, 0xa0908402,
63 	0xc24012a0, 0x17c07c1f, 0x8105a001, 0xd8200404, 0x17c07c1f, 0x80b08402,
64 	0xc2401760, 0x17c07c1f, 0x1a40001f, 0x10006238, 0x81012001, 0xd8200504,
65 	0x17c07c1f, 0xa0910402, 0xc24012a0, 0x17c07c1f, 0x81062001, 0xd82005c4,
66 	0x17c07c1f, 0x80b10402, 0xc2401760, 0x17c07c1f, 0x1a40001f, 0x1000623c,
67 	0x8101a001, 0xd82006c4, 0x17c07c1f, 0xa0918402, 0xc24012a0, 0x17c07c1f,
68 	0x8106a001, 0xd8200784, 0x17c07c1f, 0x80b18402, 0xc2401760, 0x17c07c1f,
69 	0x1a40001f, 0x10006298, 0x81022001, 0xd8200884, 0x17c07c1f, 0xa0920402,
70 	0xc24012a0, 0x17c07c1f, 0x81072001, 0xd8200944, 0x17c07c1f, 0x80b20402,
71 	0xc2401760, 0x17c07c1f, 0x1a40001f, 0x1000629c, 0x8102a001, 0xd8200a44,
72 	0x17c07c1f, 0xa0928402, 0xc24012a0, 0x17c07c1f, 0x8107a001, 0xd8200b04,
73 	0x17c07c1f, 0x80b28402, 0xc2401760, 0x17c07c1f, 0x1a40001f, 0x100062c4,
74 	0x81032001, 0xd8200c04, 0x17c07c1f, 0xa0930402, 0xc24012a0, 0x17c07c1f,
75 	0x81082001, 0xd8200cc4, 0x17c07c1f, 0x80b30402, 0xc2401760, 0x17c07c1f,
76 	0x1a40001f, 0x100062c0, 0x8103a001, 0xd8200dc4, 0x17c07c1f, 0xa0938402,
77 	0xc24012a0, 0x17c07c1f, 0x8108a001, 0xd8200e84, 0x17c07c1f, 0x80b38402,
78 	0xc2401760, 0x17c07c1f, 0x1a40001f, 0x10006214, 0x81042001, 0xd8200f84,
79 	0x17c07c1f, 0xa0940402, 0xc24012a0, 0x17c07c1f, 0x81092001, 0xd8201044,
80 	0x17c07c1f, 0x80b40402, 0xc2401760, 0x17c07c1f, 0x1a40001f, 0x100062cc,
81 	0x8104a001, 0xd8201144, 0x17c07c1f, 0xa0948402, 0xc24012a0, 0x17c07c1f,
82 	0x8109a001, 0xd8201204, 0x17c07c1f, 0x80b48402, 0xc2401760, 0x17c07c1f,
83 	0x1900001f, 0x10006b6c, 0xe1000002, 0xf0000000, 0x17c07c1f, 0xe2603f16,
84 	0xe2603f1e, 0x1b80001f, 0x00000020, 0xe2603f0e, 0xe2603f0c, 0xe2603f0d,
85 	0xe260000d, 0x1b80001f, 0x20000080, 0x1a90001f, 0x10001220, 0x69200009,
86 	0x1000623c, 0xd8001564, 0x17c07c1f, 0x69200009, 0x10006214, 0xd8001644,
87 	0x17c07c1f, 0xd00016e0, 0x17c07c1f, 0x1900001f, 0x10001220, 0x8a80000a,
88 	0xfffffffc, 0xe100000a, 0xd00016e0, 0x17c07c1f, 0x1900001f, 0x10001220,
89 	0x8a80000a, 0xff1fbfff, 0xe100000a, 0x1b80001f, 0x20000080, 0xf0000000,
90 	0x17c07c1f, 0x1a90001f, 0x10001220, 0x69200009, 0x1000623c, 0xd80018e4,
91 	0x17c07c1f, 0x69200009, 0x10006214, 0xd80019c4, 0x17c07c1f, 0xd0001a60,
92 	0x17c07c1f, 0x1900001f, 0x10001220, 0xaa80000a, 0x00000003, 0xe100000a,
93 	0xd0001a60, 0x17c07c1f, 0x1900001f, 0x10001220, 0xaa80000a, 0x00e04000,
94 	0xe100000a, 0x1b80001f, 0x20000080, 0x69200009, 0x10006214, 0xd8001b84,
95 	0x17c07c1f, 0xe2600f0d, 0xd0001ba0, 0x17c07c1f, 0xe2603f0d, 0x1b80001f,
96 	0x20000080, 0xe2600f0f, 0xe2600f0e, 0xe2600f1e, 0xe2600f1a, 0xe2600f12,
97 	0xf0000000, 0x17c07c1f, 0xe2e00036, 0xe2e0003e, 0x1b80001f, 0x00000020,
98 	0xe2e0003c, 0xe8208000, 0x10006244, 0x00000000, 0x1b80001f, 0x20000080,
99 	0xe2e0007c, 0x1b80001f, 0x20000003, 0xe2e0005c, 0xe2e0004c, 0xe2e0004d,
100 	0xf0000000, 0x17c07c1f, 0xe2e0004f, 0xe2e0006f, 0xe2e0002f, 0xe8208000,
101 	0x10006244, 0x00000001, 0x1b80001f, 0x20000080, 0xe2e0002e, 0xe2e0003e,
102 	0xe2e0003a, 0xe2e00032, 0x1b80001f, 0x00000020, 0x1910001f, 0x10006b6c,
103 	0x09000004, 0x00100000, 0x1a10001f, 0x10006b6c, 0xe2000004, 0xf0000000,
104 	0x17c07c1f, 0xe2e00036, 0xe2e0003e, 0x1b80001f, 0x00000020, 0xe2e0003c,
105 	0xe2a00000, 0x1b80001f, 0x20000080, 0xe2e0007c, 0x1b80001f, 0x20000003,
106 	0xe2e0005c, 0xe2e0004c, 0xe2e0004d, 0xf0000000, 0x17c07c1f, 0xe2e0004f,
107 	0xe2e0006f, 0xe2e0002f, 0xe2a00001, 0x1b80001f, 0x20000080, 0xe2e0002e,
108 	0xe2e0003e, 0xe2e0003a, 0xe2e00032, 0xf0000000, 0x17c07c1f, 0xe2e00026,
109 	0xe2e0002e, 0x1b80001f, 0x00000020, 0x1a00001f, 0x100062b4, 0x1910001f,
110 	0x100062b4, 0x81322804, 0xe2000004, 0x81202804, 0xe2000004, 0x1b80001f,
111 	0x20000080, 0xe2e0000e, 0xe2e0000c, 0xe2e0000d, 0xf0000000, 0x17c07c1f,
112 	0xe2e0002d, 0x1a00001f, 0x100062b4, 0x1910001f, 0x100062b4, 0xa1002804,
113 	0xe2000004, 0xa1122804, 0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0002f,
114 	0xe2e0002b, 0xe2e00023, 0x1b80001f, 0x00000020, 0xe2e00022, 0xf0000000,
115 	0x17c07c1f, 0x1900001f, 0x1020020c, 0x1a10001f, 0x1020020c, 0xaa000008,
116 	0x00000001, 0xe1000008, 0x1910001f, 0x10006720, 0x820c9001, 0xd8202b08,
117 	0x17c07c1f, 0x1900001f, 0x10001220, 0x1a10001f, 0x10001220, 0xa21f0408,
118 	0xe1000008, 0x1b80001f, 0x20000080, 0xe2e0006d, 0xe2e0002d, 0x1a00001f,
119 	0x100062b8, 0x1910001f, 0x100062b8, 0xa9000004, 0x00000001, 0xe2000004,
120 	0x1b80001f, 0x20000080, 0xe2e0002c, 0xe2e0003c, 0xe2e0003e, 0xe2e0003a,
121 	0xe2e00032, 0x1b80001f, 0x00000020, 0x1900001f, 0x10006404, 0x1a10001f,
122 	0x10006404, 0xa2168408, 0xe1000008, 0xf0000000, 0x17c07c1f, 0x1a10001f,
123 	0x10006918, 0x81022001, 0xb102a081, 0xb1062081, 0xb106a081, 0xb1003081,
124 	0xd8203624, 0x17c07c1f, 0x1900001f, 0x10006404, 0x1a10001f, 0x10006404,
125 	0x8a000008, 0x0000dfff, 0xe1000008, 0xe2e00036, 0xe2e0003e, 0x1b80001f,
126 	0x00000020, 0xe2e0002e, 0x1a00001f, 0x100062b8, 0x1910001f, 0x100062b8,
127 	0x89000004, 0x0000fffe, 0xe2000004, 0x1b80001f, 0x20000080, 0xe2e0006e,
128 	0xe2e0004e, 0xe2e0004c, 0xe2e0004d, 0x1900001f, 0x10001220, 0x1a10001f,
129 	0x10001220, 0x8a000008, 0xbfffffff, 0xe1000008, 0x1b80001f, 0x20000080,
130 	0x1900001f, 0x1020020c, 0x1a10001f, 0x1020020c, 0x8a000008, 0xfffffffe,
131 	0xe1000008, 0xf0000000, 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, 0x1b00001f, 0x21000001, 0x1b80001f, 0xd0010000, 0x69200006,
148 	0xbeefbeef, 0xd8204664, 0x17c07c1f, 0x1910001f, 0x10006358, 0x810b1001,
149 	0xd8004324, 0x17c07c1f, 0x1980001f, 0xdeaddead, 0x69200006, 0xabcdabcd,
150 	0xd8204404, 0x17c07c1f, 0x88900001, 0x10006814, 0x1910001f, 0x10006400,
151 	0x81271002, 0x1880001f, 0x10006600, 0xe0800004, 0x1910001f, 0x10006358,
152 	0x810b1001, 0xd8004584, 0x17c07c1f, 0x1980001f, 0x12345678, 0x60a07c05,
153 	0x89100002, 0x10006600, 0x80801001, 0xd8007d42, 0x17c07c1f, 0x1890001f,
154 	0x10006b00, 0x82090801, 0xc8800008, 0x17c07c1f, 0x1a10001f, 0x10006720,
155 	0x82002001, 0x82201408, 0xd8204968, 0x17c07c1f, 0x1a40001f, 0x10006200,
156 	0x1a80001f, 0x1000625c, 0xc24023e0, 0x17c07c1f, 0xa1400405, 0x1a10001f,
157 	0x10006720, 0x8200a001, 0x82209408, 0xd8204b08, 0x17c07c1f, 0x1a40001f,
158 	0x10006218, 0x1a80001f, 0x10006264, 0xc24023e0, 0x17c07c1f, 0xa1508405,
159 	0x1a10001f, 0x10006720, 0x82012001, 0x82211408, 0xd8204ca8, 0x17c07c1f,
160 	0x1a40001f, 0x1000621c, 0x1a80001f, 0x1000626c, 0xc24023e0, 0x17c07c1f,
161 	0xa1510405, 0x1a10001f, 0x10006720, 0x8201a001, 0x82219408, 0xd8204e48,
162 	0x17c07c1f, 0x1a40001f, 0x10006220, 0x1a80001f, 0x10006274, 0xc24023e0,
163 	0x17c07c1f, 0xa1518405, 0x1a10001f, 0x10006720, 0x82022001, 0x82221408,
164 	0xd8204fc8, 0x17c07c1f, 0x1a40001f, 0x100062a0, 0x1280041f, 0xc24027c0,
165 	0x17c07c1f, 0xa1520405, 0x1a10001f, 0x10006720, 0x8202a001, 0x82229408,
166 	0xd8205148, 0x17c07c1f, 0x1a40001f, 0x100062a4, 0x1290841f, 0xc24027c0,
167 	0x17c07c1f, 0xa1528405, 0x1a10001f, 0x10006720, 0x82032001, 0x82231408,
168 	0xd8205228, 0x17c07c1f, 0xa1530405, 0x1a10001f, 0x10006720, 0x8203a001,
169 	0x82239408, 0xd8205308, 0x17c07c1f, 0xa1538405, 0x1a10001f, 0x10006b00,
170 	0x8108a001, 0xd8205ee4, 0x17c07c1f, 0x1a10001f, 0x10006610, 0x8104a001,
171 	0xb1052081, 0xb105a081, 0xb1062081, 0xd8005904, 0x17c07c1f, 0x81042001,
172 	0xd8205904, 0x17c07c1f, 0x1900001f, 0x1020002c, 0x1a10001f, 0x1020002c,
173 	0xaa000008, 0x00000010, 0xe1000008, 0x1910001f, 0x10006720, 0x820c1001,
174 	0xd82055e8, 0x17c07c1f, 0x1900001f, 0x10001250, 0x1a10001f, 0x10001250,
175 	0xa2110408, 0xe1000008, 0x1b80001f, 0x20000080, 0x1900001f, 0x10001220,
176 	0x1a10001f, 0x10001220, 0xa21e8408, 0xe1000008, 0x1b80001f, 0x20000080,
177 	0x1a40001f, 0x10006208, 0xc2401f00, 0x17c07c1f, 0x1910001f, 0x10006610,
178 	0x81041001, 0xd8005ee4, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81002001,
179 	0xb100a081, 0xb1012081, 0xb101a081, 0xb1042081, 0xb104a081, 0xb1052081,
180 	0xb105a081, 0xb1003081, 0xd8205ee4, 0x17c07c1f, 0x1a40001f, 0x10006208,
181 	0xc2401cc0, 0x17c07c1f, 0x1900001f, 0x10001250, 0x1a10001f, 0x10001250,
182 	0x8a000008, 0xfffffffb, 0xe1000008, 0x1b80001f, 0x20000080, 0x1900001f,
183 	0x10001220, 0x1a10001f, 0x10001220, 0x8a000008, 0xdfffffff, 0xe1000008,
184 	0x1b80001f, 0x20000080, 0x1900001f, 0x1020002c, 0x1a10001f, 0x1020002c,
185 	0x8a000008, 0xffffffef, 0xe1000008, 0x1a10001f, 0x10006b00, 0x81082001,
186 	0xd8206164, 0x17c07c1f, 0x1a10001f, 0x10006610, 0x81082001, 0xb108a081,
187 	0xd8006164, 0x17c07c1f, 0x1a10001f, 0x10006610, 0x8107a001, 0xd8206164,
188 	0x17c07c1f, 0x1a40001f, 0x100062b0, 0xc2402a20, 0x17c07c1f, 0x1b80001f,
189 	0x20000208, 0xd8207d0c, 0x17c07c1f, 0x1910001f, 0x10006610, 0x81079001,
190 	0xd8006304, 0x17c07c1f, 0x1a40001f, 0x100062b0, 0xc2402fe0, 0x17c07c1f,
191 	0x81001401, 0xd8206684, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81002001,
192 	0xb1042081, 0xb1003081, 0xb10c3081, 0xd8206684, 0x17c07c1f, 0x1a40001f,
193 	0x10006200, 0x1a80001f, 0x1000625c, 0xc24021e0, 0x17c07c1f, 0x89400005,
194 	0xfffffffe, 0xe8208000, 0x10006f00, 0x00000000, 0xe8208000, 0x10006b30,
195 	0x00000000, 0xe8208000, 0x100063e0, 0x00000001, 0x81009401, 0xd82069e4,
196 	0x17c07c1f, 0x1a10001f, 0x10006918, 0x8100a001, 0xb104a081, 0xb1003081,
197 	0xd82069e4, 0x17c07c1f, 0x1a40001f, 0x10006218, 0x1a80001f, 0x10006264,
198 	0xc24021e0, 0x17c07c1f, 0x89400005, 0xfffffffd, 0xe8208000, 0x10006f04,
199 	0x00000000, 0xe8208000, 0x10006b34, 0x00000000, 0xe8208000, 0x100063e0,
200 	0x00000002, 0x81011401, 0xd8206d44, 0x17c07c1f, 0x1a10001f, 0x10006918,
201 	0x81012001, 0xb1052081, 0xb1003081, 0xd8206d44, 0x17c07c1f, 0x1a40001f,
202 	0x1000621c, 0x1a80001f, 0x1000626c, 0xc24021e0, 0x17c07c1f, 0x89400005,
203 	0xfffffffb, 0xe8208000, 0x10006f08, 0x00000000, 0xe8208000, 0x10006b38,
204 	0x00000000, 0xe8208000, 0x100063e0, 0x00000004, 0x81019401, 0xd82070a4,
205 	0x17c07c1f, 0x1a10001f, 0x10006918, 0x8101a001, 0xb105a081, 0xb1003081,
206 	0xd82070a4, 0x17c07c1f, 0x1a40001f, 0x10006220, 0x1a80001f, 0x10006274,
207 	0xc24021e0, 0x17c07c1f, 0x89400005, 0xfffffff7, 0xe8208000, 0x10006f0c,
208 	0x00000000, 0xe8208000, 0x10006b3c, 0x00000000, 0xe8208000, 0x100063e0,
209 	0x00000008, 0x1910001f, 0x10006610, 0x81079001, 0xd82077c4, 0x17c07c1f,
210 	0x81021401, 0xd8207484, 0x17c07c1f, 0x1a10001f, 0x10006918, 0x81022001,
211 	0xb1062081, 0xb1003081, 0xd8207484, 0x17c07c1f, 0x1a40001f, 0x100062a0,
212 	0x1280041f, 0xc2402560, 0x17c07c1f, 0x89400005, 0xffffffef, 0xe8208000,
213 	0x10006f10, 0x00000000, 0xe8208000, 0x10006b40, 0x00000000, 0xe8208000,
214 	0x100063e0, 0x00000010, 0x81029401, 0xd82077c4, 0x17c07c1f, 0x1a10001f,
215 	0x10006918, 0x8102a001, 0xb106a081, 0xb1003081, 0xd82077c4, 0x17c07c1f,
216 	0x1a40001f, 0x100062a4, 0x1290841f, 0xc2402560, 0x17c07c1f, 0x89400005,
217 	0xffffffdf, 0xe8208000, 0x10006f14, 0x00000000, 0xe8208000, 0x10006b44,
218 	0x00000000, 0xe8208000, 0x100063e0, 0x00000020, 0x81031401, 0xd8207a64,
219 	0x17c07c1f, 0x1a10001f, 0x10006918, 0x81032001, 0xb1072081, 0xb1003081,
220 	0xd8207a64, 0x17c07c1f, 0x89400005, 0xffffffbf, 0xe8208000, 0x10006f18,
221 	0x00000000, 0xe8208000, 0x10006b48, 0x00000000, 0xe8208000, 0x100063e0,
222 	0x00000040, 0x81039401, 0xd8207d04, 0x17c07c1f, 0x1a10001f, 0x10006918,
223 	0x8103a001, 0xb107a081, 0xb1003081, 0xd8207d04, 0x17c07c1f, 0x89400005,
224 	0xffffff7f, 0xe8208000, 0x10006f1c, 0x00000000, 0xe8208000, 0x10006b4c,
225 	0x00000000, 0xe8208000, 0x100063e0, 0x00000080, 0xd0004220, 0x17c07c1f,
226 	0xe8208000, 0x10006600, 0x00000000, 0x1ac0001f, 0x55aa55aa, 0x1940001f,
227 	0xaa55aa55, 0x1b80001f, 0x00001000, 0xf0000000, 0x17c07c1f
228 };
229 
230 static const struct pcm_desc mcdi_pcm = {
231 	.version = "pcm_mcdi_mt8173_20151110_V4",
232 	.base = mcdi_binary,
233 	.size = 1013,
234 	.sess = 2,
235 	.replace = 0,
236 };
237 
238 static struct pwr_ctrl mcdi_ctrl = {
239 	.wake_src = WAKE_SRC_FOR_MCDI,
240 	.wake_src_md32 = 0,
241 	.wfi_op = WFI_OP_OR,
242 	.mcusys_idle_mask = 1,
243 	.ca7top_idle_mask = 1,
244 	.ca15top_idle_mask = 1,
245 	.disp_req_mask = 1,
246 	.mfg_req_mask = 1,
247 	.md32_req_mask = 1,
248 };
249 
250 static const struct spm_lp_scen spm_mcdi = {
251 	.pcmdesc = &mcdi_pcm,
252 	.pwrctrl = &mcdi_ctrl,
253 };
254 
255 void spm_mcdi_cpu_wake_up_event(int wake_up_event, int disable_dormant_power)
256 {
257 	if (((mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) & 0x1) == 1)
258 	    && ((mmio_read_32(SPM_CLK_CON) & CC_DISABLE_DORM_PWR) == 0)) {
259 		/* MCDI is offload? */
260 		INFO("%s: SPM_SLEEP_CPU_WAKEUP_EVENT:%x, SPM_CLK_CON %x",
261 			__func__, mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT),
262 			mmio_read_32(SPM_CLK_CON));
263 		return;
264 	}
265 	/* Inform SPM that CPU wants to program CPU_WAKEUP_EVENT and
266 	 * DISABLE_CPU_DROM */
267 	mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_HANDSHAKE_SYNC);
268 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
269 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
270 
271 	/* Wait SPM's response, can't use sleep api */
272 	while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_HANDSHAKE_ACK)
273 		;
274 
275 	if (disable_dormant_power) {
276 		mmio_setbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
277 		while (mmio_read_32(SPM_CLK_CON) !=
278 			(mmio_read_32(SPM_CLK_CON) | CC_DISABLE_DORM_PWR))
279 			;
280 
281 	} else {
282 		mmio_clrbits_32(SPM_CLK_CON, CC_DISABLE_DORM_PWR);
283 		while (mmio_read_32(SPM_CLK_CON) !=
284 			(mmio_read_32(SPM_CLK_CON) & ~CC_DISABLE_DORM_PWR))
285 			;
286 	}
287 
288 	mmio_write_32(SPM_SLEEP_CPU_WAKEUP_EVENT, wake_up_event);
289 
290 	while (mmio_read_32(SPM_SLEEP_CPU_WAKEUP_EVENT) != wake_up_event)
291 		;
292 
293 	/* Inform SPM to see updated setting */
294 	mmio_write_32(SPM_PCM_REG_DATA_INI, PCM_MCDI_UPDATE_INFORM);
295 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
296 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
297 
298 	while (mmio_read_32(SPM_PCM_REG6_DATA) != PCM_MCDI_CKECK_DONE)
299 		;
300 	/* END OF sequence */
301 
302 	mmio_write_32(SPM_PCM_REG_DATA_INI, 0x0);
303 	mmio_write_32(SPM_PCM_PWR_IO_EN, PCM_RF_SYNC_R6);
304 	mmio_write_32(SPM_PCM_PWR_IO_EN, 0);
305 }
306 
307 void spm_mcdi_wakeup_all_cores(void)
308 {
309 	if (is_mcdi_ready() == 0)
310 		return;
311 
312 	spm_mcdi_cpu_wake_up_event(1, 1);
313 	while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_ALL_CORE_AWAKE)
314 		;
315 	spm_mcdi_cpu_wake_up_event(1, 0);
316 	while (mmio_read_32(SPM_PCM_REG5_DATA) != PCM_MCDI_OFFLOADED)
317 		;
318 
319 	spm_clean_after_wakeup();
320 	clear_all_ready();
321 }
322 
323 static void spm_mcdi_wfi_sel_enter(unsigned long mpidr)
324 {
325 	int core_id_val = mpidr & MPIDR_CPU_MASK;
326 	int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
327 
328 	/* SPM WFI Select by core number */
329 	if (cluster_id) {
330 		switch (core_id_val) {
331 		case 0:
332 			mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 1);
333 			mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 1);
334 			break;
335 		case 1:
336 			mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 1);
337 			mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 1);
338 			break;
339 		case 2:
340 			mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 1);
341 			mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 1);
342 			break;
343 		case 3:
344 			mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 1);
345 			mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 1);
346 			break;
347 		default:
348 			break;
349 		}
350 	} else {
351 		switch (core_id_val) {
352 		case 0:
353 			mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 1);
354 			mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 1);
355 			break;
356 		case 1:
357 			mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 1);
358 			mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 1);
359 			break;
360 		case 2:
361 			mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 1);
362 			mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 1);
363 			break;
364 		case 3:
365 			mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 1);
366 			mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 1);
367 			break;
368 		default:
369 			break;
370 		}
371 	}
372 }
373 
374 static void spm_mcdi_wfi_sel_leave(unsigned long mpidr)
375 {
376 	int core_id_val = mpidr & MPIDR_CPU_MASK;
377 	int cluster_id = (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
378 
379 	/* SPM WFI Select by core number */
380 	if (cluster_id) {
381 		switch (core_id_val) {
382 		case 0:
383 			mmio_write_32(SPM_SLEEP_CA15_WFI0_EN, 0);
384 			mmio_write_32(SPM_CA15_CPU0_IRQ_MASK, 0);
385 			break;
386 		case 1:
387 			mmio_write_32(SPM_SLEEP_CA15_WFI1_EN, 0);
388 			mmio_write_32(SPM_CA15_CPU1_IRQ_MASK, 0);
389 			break;
390 		case 2:
391 			mmio_write_32(SPM_SLEEP_CA15_WFI2_EN, 0);
392 			mmio_write_32(SPM_CA15_CPU2_IRQ_MASK, 0);
393 			break;
394 		case 3:
395 			mmio_write_32(SPM_SLEEP_CA15_WFI3_EN, 0);
396 			mmio_write_32(SPM_CA15_CPU3_IRQ_MASK, 0);
397 			break;
398 		default:
399 			break;
400 		}
401 	} else {
402 		switch (core_id_val) {
403 		case 0:
404 			mmio_write_32(SPM_SLEEP_CA7_WFI0_EN, 0);
405 			mmio_write_32(SPM_CA7_CPU0_IRQ_MASK, 0);
406 			break;
407 		case 1:
408 			mmio_write_32(SPM_SLEEP_CA7_WFI1_EN, 0);
409 			mmio_write_32(SPM_CA7_CPU1_IRQ_MASK, 0);
410 			break;
411 		case 2:
412 			mmio_write_32(SPM_SLEEP_CA7_WFI2_EN, 0);
413 			mmio_write_32(SPM_CA7_CPU2_IRQ_MASK, 0);
414 			break;
415 		case 3:
416 			mmio_write_32(SPM_SLEEP_CA7_WFI3_EN, 0);
417 			mmio_write_32(SPM_CA7_CPU3_IRQ_MASK, 0);
418 			break;
419 		default:
420 			break;
421 		}
422 	}
423 }
424 
425 static void spm_mcdi_set_cputop_pwrctrl_for_cluster_off(unsigned long mpidr)
426 {
427 	unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
428 	unsigned long cpu_id = mpidr & MPIDR_CPU_MASK;
429 	unsigned int pwr_status, shift, i, flag = 0;
430 
431 	pwr_status = mmio_read_32(SPM_PWR_STATUS) |
432 				 mmio_read_32(SPM_PWR_STATUS_2ND);
433 
434 	if (cluster_id) {
435 		for (i = 0; i < PLATFORM_CLUSTER1_CORE_COUNT; i++) {
436 			if (i == cpu_id)
437 				continue;
438 			shift = i + PCM_MCDI_CA72_PWRSTA_SHIFT;
439 			flag |= (pwr_status & (1 << shift)) >> shift;
440 		}
441 		if (!flag)
442 			mmio_setbits_32(SPM_PCM_RESERVE,
443 					PCM_MCDI_CA72_CPUTOP_PWRCTL);
444 	} else {
445 		for (i = 0; i < PLATFORM_CLUSTER0_CORE_COUNT; i++) {
446 			if (i == cpu_id)
447 				continue;
448 			shift = i + PCM_MCDI_CA53_PWRSTA_SHIFT;
449 			flag |= (pwr_status & (1 << shift)) >> shift;
450 		}
451 		if (!flag)
452 			mmio_setbits_32(SPM_PCM_RESERVE,
453 					PCM_MCDI_CA53_CPUTOP_PWRCTL);
454 	}
455 }
456 
457 static void spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(unsigned long mpidr)
458 {
459 	unsigned long cluster_id = mpidr & MPIDR_CLUSTER_MASK;
460 
461 	if (cluster_id)
462 		mmio_clrbits_32(SPM_PCM_RESERVE,
463 				PCM_MCDI_CA72_CPUTOP_PWRCTL);
464 	else
465 		mmio_clrbits_32(SPM_PCM_RESERVE,
466 				PCM_MCDI_CA53_CPUTOP_PWRCTL);
467 }
468 
469 void spm_mcdi_prepare_for_mtcmos(void)
470 {
471 	const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
472 	struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
473 
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 }
486 
487 void spm_mcdi_prepare_for_off_state(unsigned long mpidr, unsigned int afflvl)
488 {
489 	const struct pcm_desc *pcmdesc = spm_mcdi.pcmdesc;
490 	struct pwr_ctrl *pwrctrl = spm_mcdi.pwrctrl;
491 
492 	spm_lock_get();
493 	if (is_mcdi_ready() == 0) {
494 		if (is_hotplug_ready() == 1)
495 			spm_clear_hotplug();
496 		set_pwrctrl_pcm_flags(pwrctrl, 0);
497 		spm_reset_and_init_pcm();
498 		spm_kick_im_to_fetch(pcmdesc);
499 		spm_set_power_control(pwrctrl);
500 		spm_set_wakeup_event(pwrctrl);
501 		spm_kick_pcm_to_run(pwrctrl);
502 		set_mcdi_ready();
503 	}
504 	spm_mcdi_wfi_sel_enter(mpidr);
505 	if (afflvl == MPIDR_AFFLVL1)
506 		spm_mcdi_set_cputop_pwrctrl_for_cluster_off(mpidr);
507 	spm_lock_release();
508 }
509 
510 void spm_mcdi_finish_for_on_state(unsigned long mpidr, unsigned int afflvl)
511 {
512 	unsigned long linear_id = platform_get_core_pos(mpidr);
513 
514 	spm_lock_get();
515 	spm_mcdi_clear_cputop_pwrctrl_for_cluster_on(mpidr);
516 	spm_mcdi_wfi_sel_leave(mpidr);
517 	mmio_write_32(SPM_PCM_SW_INT_CLEAR, (0x1 << linear_id));
518 	spm_lock_release();
519 }
520