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