1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /*! 8 * File containing client-side RPC functions for the PM service. These 9 * functions are ported to clients that communicate to the SC. 10 * 11 * @addtogroup PM_SVC 12 * @{ 13 */ 14 15 /* Includes */ 16 17 #include <stdlib.h> 18 19 #include <sci/sci_types.h> 20 #include <sci/svc/rm/sci_rm_api.h> 21 #include <sci/svc/pm/sci_pm_api.h> 22 #include <sci/sci_rpc.h> 23 24 #include "sci_pm_rpc.h" 25 26 /* Local Defines */ 27 28 /* Local Types */ 29 30 /* Local Functions */ 31 32 sc_err_t sc_pm_set_sys_power_mode(sc_ipc_t ipc, sc_pm_power_mode_t mode) 33 { 34 sc_rpc_msg_t msg; 35 uint8_t result; 36 37 RPC_VER(&msg) = SC_RPC_VERSION; 38 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 39 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_SYS_POWER_MODE; 40 RPC_U8(&msg, 0U) = (uint8_t)mode; 41 RPC_SIZE(&msg) = 2U; 42 43 sc_call_rpc(ipc, &msg, SC_FALSE); 44 45 result = RPC_R8(&msg); 46 return (sc_err_t)result; 47 } 48 49 sc_err_t sc_pm_set_partition_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt, 50 sc_pm_power_mode_t mode) 51 { 52 sc_rpc_msg_t msg; 53 uint8_t result; 54 55 RPC_VER(&msg) = SC_RPC_VERSION; 56 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 57 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_PARTITION_POWER_MODE; 58 RPC_U8(&msg, 0U) = (uint8_t)pt; 59 RPC_U8(&msg, 1U) = (uint8_t)mode; 60 RPC_SIZE(&msg) = 2U; 61 62 sc_call_rpc(ipc, &msg, SC_FALSE); 63 64 result = RPC_R8(&msg); 65 return (sc_err_t)result; 66 } 67 68 sc_err_t sc_pm_get_sys_power_mode(sc_ipc_t ipc, sc_rm_pt_t pt, 69 sc_pm_power_mode_t *mode) 70 { 71 sc_rpc_msg_t msg; 72 uint8_t result; 73 74 RPC_VER(&msg) = SC_RPC_VERSION; 75 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 76 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_SYS_POWER_MODE; 77 RPC_U8(&msg, 0U) = (uint8_t)pt; 78 RPC_SIZE(&msg) = 2U; 79 80 sc_call_rpc(ipc, &msg, SC_FALSE); 81 82 result = RPC_R8(&msg); 83 if (mode != NULL) { 84 *mode = RPC_U8(&msg, 0U); 85 } 86 87 return (sc_err_t)result; 88 } 89 90 sc_err_t sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource, 91 sc_pm_power_mode_t mode) 92 { 93 sc_rpc_msg_t msg; 94 uint8_t result; 95 96 RPC_VER(&msg) = SC_RPC_VERSION; 97 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 98 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_RESOURCE_POWER_MODE; 99 RPC_U16(&msg, 0U) = (uint16_t)resource; 100 RPC_U8(&msg, 2U) = (uint8_t)mode; 101 RPC_SIZE(&msg) = 2U; 102 103 sc_call_rpc(ipc, &msg, SC_FALSE); 104 105 result = RPC_R8(&msg); 106 return (sc_err_t)result; 107 } 108 109 sc_err_t sc_pm_get_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource, 110 sc_pm_power_mode_t *mode) 111 { 112 sc_rpc_msg_t msg; 113 uint8_t result; 114 115 RPC_VER(&msg) = SC_RPC_VERSION; 116 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 117 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_RESOURCE_POWER_MODE; 118 RPC_U16(&msg, 0U) = (uint16_t)resource; 119 RPC_SIZE(&msg) = 2U; 120 121 sc_call_rpc(ipc, &msg, SC_FALSE); 122 123 result = RPC_R8(&msg); 124 if (mode != NULL) { 125 *mode = RPC_U8(&msg, 0U); 126 } 127 128 return (sc_err_t)result; 129 } 130 131 sc_err_t sc_pm_req_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource, 132 sc_pm_power_mode_t mode) 133 { 134 sc_rpc_msg_t msg; 135 uint8_t result; 136 137 RPC_VER(&msg) = SC_RPC_VERSION; 138 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 139 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_LOW_POWER_MODE; 140 RPC_U16(&msg, 0U) = (uint16_t)resource; 141 RPC_U8(&msg, 2U) = (uint8_t)mode; 142 RPC_SIZE(&msg) = 2U; 143 144 sc_call_rpc(ipc, &msg, SC_FALSE); 145 146 result = RPC_R8(&msg); 147 return (sc_err_t)result; 148 } 149 150 sc_err_t sc_pm_req_cpu_low_power_mode(sc_ipc_t ipc, sc_rsrc_t resource, 151 sc_pm_power_mode_t mode, 152 sc_pm_wake_src_t wake_src) 153 { 154 sc_rpc_msg_t msg; 155 uint8_t result; 156 157 RPC_VER(&msg) = SC_RPC_VERSION; 158 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 159 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_CPU_LOW_POWER_MODE; 160 RPC_U16(&msg, 0U) = (uint16_t)resource; 161 RPC_U8(&msg, 2U) = (uint8_t)mode; 162 RPC_U8(&msg, 3U) = (uint8_t)wake_src; 163 RPC_SIZE(&msg) = 2U; 164 165 sc_call_rpc(ipc, &msg, SC_FALSE); 166 167 result = RPC_R8(&msg); 168 return (sc_err_t)result; 169 } 170 171 sc_err_t sc_pm_set_cpu_resume_addr(sc_ipc_t ipc, sc_rsrc_t resource, 172 sc_faddr_t address) 173 { 174 sc_rpc_msg_t msg; 175 uint8_t result; 176 177 RPC_VER(&msg) = SC_RPC_VERSION; 178 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 179 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CPU_RESUME_ADDR; 180 RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U); 181 RPC_U32(&msg, 4U) = (uint32_t)address; 182 RPC_U16(&msg, 8U) = (uint16_t)resource; 183 RPC_SIZE(&msg) = 4U; 184 185 sc_call_rpc(ipc, &msg, SC_FALSE); 186 187 result = RPC_R8(&msg); 188 return (sc_err_t)result; 189 } 190 191 sc_err_t sc_pm_set_cpu_resume(sc_ipc_t ipc, sc_rsrc_t resource, 192 sc_bool_t isPrimary, sc_faddr_t address) 193 { 194 sc_rpc_msg_t msg; 195 uint8_t result; 196 197 RPC_VER(&msg) = SC_RPC_VERSION; 198 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 199 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CPU_RESUME; 200 RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U); 201 RPC_U32(&msg, 4U) = (uint32_t)address; 202 RPC_U16(&msg, 8U) = (uint16_t)resource; 203 RPC_U8(&msg, 10U) = (uint8_t)isPrimary; 204 RPC_SIZE(&msg) = 4U; 205 206 sc_call_rpc(ipc, &msg, SC_FALSE); 207 208 result = RPC_R8(&msg); 209 return (sc_err_t)result; 210 } 211 212 sc_err_t sc_pm_req_sys_if_power_mode(sc_ipc_t ipc, sc_rsrc_t resource, 213 sc_pm_sys_if_t sys_if, 214 sc_pm_power_mode_t hpm, 215 sc_pm_power_mode_t lpm) 216 { 217 sc_rpc_msg_t msg; 218 uint8_t result; 219 220 RPC_VER(&msg) = SC_RPC_VERSION; 221 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 222 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REQ_SYS_IF_POWER_MODE; 223 RPC_U16(&msg, 0U) = (uint16_t)resource; 224 RPC_U8(&msg, 2U) = (uint8_t)sys_if; 225 RPC_U8(&msg, 3U) = (uint8_t)hpm; 226 RPC_U8(&msg, 4U) = (uint8_t)lpm; 227 RPC_SIZE(&msg) = 3U; 228 229 sc_call_rpc(ipc, &msg, SC_FALSE); 230 231 result = RPC_R8(&msg); 232 return (sc_err_t)result; 233 } 234 235 sc_err_t sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, 236 sc_pm_clk_t clk, sc_pm_clock_rate_t *rate) 237 { 238 sc_rpc_msg_t msg; 239 uint8_t result; 240 241 RPC_VER(&msg) = SC_RPC_VERSION; 242 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 243 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CLOCK_RATE; 244 RPC_U32(&msg, 0U) = *(uint32_t *)rate; 245 RPC_U16(&msg, 4U) = (uint16_t)resource; 246 RPC_U8(&msg, 6U) = (uint8_t)clk; 247 RPC_SIZE(&msg) = 3U; 248 249 sc_call_rpc(ipc, &msg, SC_FALSE); 250 251 *rate = RPC_U32(&msg, 0U); 252 result = RPC_R8(&msg); 253 return (sc_err_t)result; 254 } 255 256 sc_err_t sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, 257 sc_pm_clk_t clk, sc_pm_clock_rate_t *rate) 258 { 259 sc_rpc_msg_t msg; 260 uint8_t result; 261 262 RPC_VER(&msg) = SC_RPC_VERSION; 263 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 264 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_CLOCK_RATE; 265 RPC_U16(&msg, 0U) = (uint16_t)resource; 266 RPC_U8(&msg, 2U) = (uint8_t)clk; 267 RPC_SIZE(&msg) = 2U; 268 269 sc_call_rpc(ipc, &msg, SC_FALSE); 270 271 if (rate != NULL) { 272 *rate = RPC_U32(&msg, 0U); 273 } 274 275 result = RPC_R8(&msg); 276 return (sc_err_t)result; 277 } 278 279 sc_err_t sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, 280 sc_pm_clk_t clk, sc_bool_t enable, sc_bool_t autog) 281 { 282 sc_rpc_msg_t msg; 283 uint8_t result; 284 285 RPC_VER(&msg) = SC_RPC_VERSION; 286 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 287 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_CLOCK_ENABLE; 288 RPC_U16(&msg, 0U) = (uint16_t)resource; 289 RPC_U8(&msg, 2U) = (uint8_t)clk; 290 RPC_U8(&msg, 3U) = (uint8_t)enable; 291 RPC_U8(&msg, 4U) = (uint8_t)autog; 292 RPC_SIZE(&msg) = 3U; 293 294 sc_call_rpc(ipc, &msg, SC_FALSE); 295 296 result = RPC_R8(&msg); 297 return (sc_err_t)result; 298 } 299 300 sc_err_t sc_pm_set_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource, 301 sc_pm_clk_t clk, sc_pm_clk_parent_t parent) 302 { 303 sc_rpc_msg_t msg; 304 uint8_t result; 305 306 RPC_VER(&msg) = SC_RPC_VERSION; 307 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 308 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_SET_CLOCK_PARENT; 309 RPC_U16(&msg, 0U) = (uint16_t)resource; 310 RPC_U8(&msg, 2U) = (uint8_t)clk; 311 RPC_U8(&msg, 3U) = (uint8_t)parent; 312 RPC_SIZE(&msg) = 2U; 313 314 sc_call_rpc(ipc, &msg, SC_FALSE); 315 316 result = RPC_R8(&msg); 317 return (sc_err_t)result; 318 } 319 320 sc_err_t sc_pm_get_clock_parent(sc_ipc_t ipc, sc_rsrc_t resource, 321 sc_pm_clk_t clk, sc_pm_clk_parent_t *parent) 322 { 323 sc_rpc_msg_t msg; 324 uint8_t result; 325 326 RPC_VER(&msg) = SC_RPC_VERSION; 327 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 328 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_GET_CLOCK_PARENT; 329 RPC_U16(&msg, 0U) = (uint16_t)resource; 330 RPC_U8(&msg, 2U) = (uint8_t)clk; 331 RPC_SIZE(&msg) = 2U; 332 333 sc_call_rpc(ipc, &msg, SC_FALSE); 334 335 result = RPC_R8(&msg); 336 if (parent != NULL) { 337 *parent = RPC_U8(&msg, 0U); 338 } 339 340 return (sc_err_t)result; 341 } 342 343 sc_err_t sc_pm_reset(sc_ipc_t ipc, sc_pm_reset_type_t type) 344 { 345 sc_rpc_msg_t msg; 346 uint8_t result; 347 348 RPC_VER(&msg) = SC_RPC_VERSION; 349 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 350 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_RESET; 351 RPC_U8(&msg, 0U) = (uint8_t)type; 352 RPC_SIZE(&msg) = 2U; 353 354 sc_call_rpc(ipc, &msg, SC_FALSE); 355 356 result = RPC_R8(&msg); 357 return (sc_err_t)result; 358 } 359 360 sc_err_t sc_pm_reset_reason(sc_ipc_t ipc, sc_pm_reset_reason_t *reason) 361 { 362 sc_rpc_msg_t msg; 363 uint8_t result; 364 365 RPC_VER(&msg) = SC_RPC_VERSION; 366 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 367 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_RESET_REASON; 368 RPC_SIZE(&msg) = 1U; 369 370 sc_call_rpc(ipc, &msg, SC_FALSE); 371 372 result = RPC_R8(&msg); 373 if (reason != NULL) { 374 *reason = RPC_U8(&msg, 0U); 375 } 376 377 return (sc_err_t)result; 378 } 379 380 sc_err_t sc_pm_boot(sc_ipc_t ipc, sc_rm_pt_t pt, 381 sc_rsrc_t resource_cpu, sc_faddr_t boot_addr, 382 sc_rsrc_t resource_mu, sc_rsrc_t resource_dev) 383 { 384 sc_rpc_msg_t msg; 385 uint8_t result; 386 387 RPC_VER(&msg) = SC_RPC_VERSION; 388 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 389 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_BOOT; 390 RPC_U32(&msg, 0U) = (uint32_t)(boot_addr >> 32U); 391 RPC_U32(&msg, 4U) = (uint32_t)boot_addr; 392 RPC_U16(&msg, 8U) = (uint16_t)resource_cpu; 393 RPC_U16(&msg, 10U) = (uint16_t)resource_mu; 394 RPC_U16(&msg, 12U) = (uint16_t)resource_dev; 395 RPC_U8(&msg, 14U) = (uint8_t)pt; 396 RPC_SIZE(&msg) = 5U; 397 398 sc_call_rpc(ipc, &msg, SC_FALSE); 399 400 result = RPC_R8(&msg); 401 return (sc_err_t)result; 402 } 403 404 void sc_pm_reboot(sc_ipc_t ipc, sc_pm_reset_type_t type) 405 { 406 sc_rpc_msg_t msg; 407 408 RPC_VER(&msg) = SC_RPC_VERSION; 409 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 410 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REBOOT; 411 RPC_U8(&msg, 0U) = (uint8_t)type; 412 RPC_SIZE(&msg) = 2U; 413 414 sc_call_rpc(ipc, &msg, SC_TRUE); 415 } 416 417 sc_err_t sc_pm_reboot_partition(sc_ipc_t ipc, sc_rm_pt_t pt, 418 sc_pm_reset_type_t type) 419 { 420 sc_rpc_msg_t msg; 421 uint8_t result; 422 423 RPC_VER(&msg) = SC_RPC_VERSION; 424 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 425 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_REBOOT_PARTITION; 426 RPC_U8(&msg, 0U) = (uint8_t)pt; 427 RPC_U8(&msg, 1U) = (uint8_t)type; 428 RPC_SIZE(&msg) = 2U; 429 430 sc_call_rpc(ipc, &msg, SC_FALSE); 431 432 result = RPC_R8(&msg); 433 return (sc_err_t)result; 434 } 435 436 sc_err_t sc_pm_cpu_start(sc_ipc_t ipc, sc_rsrc_t resource, sc_bool_t enable, 437 sc_faddr_t address) 438 { 439 sc_rpc_msg_t msg; 440 uint8_t result; 441 442 RPC_VER(&msg) = SC_RPC_VERSION; 443 RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_PM; 444 RPC_FUNC(&msg) = (uint8_t)PM_FUNC_CPU_START; 445 RPC_U32(&msg, 0U) = (uint32_t)(address >> 32U); 446 RPC_U32(&msg, 4U) = (uint32_t)address; 447 RPC_U16(&msg, 8U) = (uint16_t)resource; 448 RPC_U8(&msg, 10U) = (uint8_t)enable; 449 RPC_SIZE(&msg) = 4U; 450 451 sc_call_rpc(ipc, &msg, SC_FALSE); 452 453 result = RPC_R8(&msg); 454 return (sc_err_t)result; 455 } 456 457 /**@}*/ 458