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