1 /* 2 * Copyright (c) 2019-2022, Xilinx, Inc. All rights reserved. 3 * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 /* 9 * Versal system level PM-API functions and communication with PMC via 10 * IPI interrupts 11 */ 12 13 #include <drivers/arm/gic_common.h> 14 #include <lib/mmio.h> 15 #include <lib/utils.h> 16 #include <plat/common/platform.h> 17 #include <platform_def.h> 18 #include <pm_api_sys.h> 19 #include <pm_client.h> 20 #include <pm_common.h> 21 #include <pm_defs.h> 22 #include <pm_ipi.h> 23 #include "pm_svc_main.h" 24 25 #define NUM_GICD_ISENABLER ((IRQ_MAX >> 5U) + 1U) 26 27 /* default shutdown/reboot scope is system(2) */ 28 static uint32_t pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM; 29 30 /** 31 * pm_get_shutdown_scope() - Get the currently set shutdown scope. 32 * 33 * Return: Shutdown scope value. 34 * 35 */ 36 uint32_t pm_get_shutdown_scope(void) 37 { 38 return pm_shutdown_scope; 39 } 40 41 /* PM API functions */ 42 43 /** 44 * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as 45 * wake sources in the XilPM. 46 * @node_id: Node id of processor. 47 * 48 */ 49 void pm_client_set_wakeup_sources(uint32_t node_id) 50 { 51 uint32_t reg_num, device_id; 52 uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX] = {0U}; 53 uint32_t isenabler1 = PLAT_GICD_BASE_VALUE + GICD_ISENABLER + 4U; 54 55 zeromem(&pm_wakeup_nodes_set, (u_register_t)sizeof(pm_wakeup_nodes_set)); 56 57 for (reg_num = 0U; reg_num < NUM_GICD_ISENABLER; reg_num++) { 58 uint32_t base_irq = reg_num << ISENABLER_SHIFT; 59 uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2)); 60 61 if (reg == 0U) { 62 continue; 63 } 64 65 while (reg != 0U) { 66 enum pm_device_node_idx node_idx; 67 uint32_t idx, irq, lowest_set = reg & (-reg); 68 enum pm_ret_status ret; 69 70 idx = (uint32_t)__builtin_ctz(lowest_set); 71 irq = base_irq + idx; 72 73 if (irq > IRQ_MAX) { 74 break; 75 } 76 77 node_idx = irq_to_pm_node_idx(irq); 78 reg &= ~lowest_set; 79 80 if (node_idx > XPM_NODEIDX_DEV_MIN) { 81 if (pm_wakeup_nodes_set[node_idx] == 0U) { 82 /* Get device ID from node index */ 83 device_id = PERIPH_DEVID((uint32_t)node_idx); 84 ret = pm_set_wakeup_source(node_id, 85 device_id, 1U, 86 SECURE_FLAG); 87 pm_wakeup_nodes_set[node_idx] = (ret == PM_RET_SUCCESS) ? 88 1U : 0U; 89 } 90 } 91 } 92 } 93 } 94 95 /** 96 * pm_handle_eemi_call() - PM call for processor to send eemi payload. 97 * @flag: 0 - Call from secure source. 98 * 1 - Call from non-secure source. 99 * @x0: Arguments received per SMC64 standard. 100 * @x1: Arguments received per SMC64 standard. 101 * @x2: Arguments received per SMC64 standard. 102 * @x3: Arguments received per SMC64 standard. 103 * @x4: Arguments received per SMC64 standard. 104 * @x5: Arguments received per SMC64 standard. 105 * @result: Payload received from firmware. 106 * 107 * Return: PM_RET_SUCCESS on success or error code. 108 * 109 */ 110 enum pm_ret_status pm_handle_eemi_call(uint32_t flag, uint32_t x0, uint32_t x1, 111 uint32_t x2, uint32_t x3, uint32_t x4, 112 uint32_t x5, uint64_t *result) 113 { 114 uint32_t payload[PAYLOAD_ARG_CNT] = {0}; 115 uint32_t module_id; 116 117 module_id = (x0 & MODULE_ID_MASK) >> 8U; 118 119 //default module id is for LIBPM 120 if (module_id == 0) { 121 module_id = LIBPM_MODULE_ID; 122 } 123 124 PM_PACK_PAYLOAD6(payload, module_id, flag, x0, x1, x2, x3, x4, x5); 125 return pm_ipi_send_sync(primary_proc, payload, (uint32_t *)result, PAYLOAD_ARG_CNT); 126 } 127 128 /** 129 * pm_self_suspend() - PM call for processor to suspend itself 130 * @nid: Node id of the processor or subsystem. 131 * @latency: Requested maximum wakeup latency (not supported). 132 * @state: Requested state. 133 * @address: Resume address. 134 * @flag: 0 - Call from secure source. 135 * 1 - Call from non-secure source. 136 * 137 * This is a blocking call, it will return only once PMU has responded. 138 * On a wakeup, resume address will be automatically set by PMU. 139 * 140 * Return: Returns status, either success or error+reason. 141 * 142 */ 143 enum pm_ret_status pm_self_suspend(uint32_t nid, 144 uint32_t latency, 145 uint32_t state, 146 uintptr_t address, uint32_t flag) 147 { 148 uint32_t payload[PAYLOAD_ARG_CNT]; 149 uint32_t cpuid = plat_my_core_pos(); 150 const struct pm_proc *proc = pm_get_proc(cpuid); 151 152 if (proc == NULL) { 153 WARN("Failed to get proc %d\n", cpuid); 154 return PM_RET_ERROR_INTERNAL; 155 } 156 157 /* 158 * Do client specific suspend operations 159 * (e.g. set powerdown request bit) 160 */ 161 pm_client_suspend(proc, state); 162 163 /* Send request to the PLM */ 164 PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, flag, PM_SELF_SUSPEND, 165 proc->node_id, latency, state, address, 166 (address >> 32)); 167 return pm_ipi_send_sync(proc, payload, NULL, 0); 168 } 169 170 /** 171 * pm_abort_suspend() - PM call to announce that a prior suspend request 172 * is to be aborted. 173 * @reason: Reason for the abort. 174 * @flag: 0 - Call from secure source. 175 * 1 - Call from non-secure source. 176 * 177 * Calling PU expects the PMU to abort the initiated suspend procedure. 178 * This is a non-blocking call without any acknowledge. 179 * 180 * Return: Returns status, either success or error+reason. 181 * 182 */ 183 enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason, uint32_t flag) 184 { 185 uint32_t payload[PAYLOAD_ARG_CNT]; 186 187 /* 188 * Do client specific abort suspend operations 189 * (e.g. enable interrupts and clear powerdown request bit) 190 */ 191 pm_client_abort_suspend(); 192 193 /* Send request to the PLM */ 194 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_ABORT_SUSPEND, 195 reason, primary_proc->node_id); 196 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 197 } 198 199 /** 200 * pm_req_suspend() - PM call to request for another PU or subsystem to 201 * be suspended gracefully. 202 * @target: Node id of the targeted PU or subsystem. 203 * @ack: Flag to specify whether acknowledge is requested. 204 * @latency: Requested wakeup latency (not supported) 205 * @state: Requested state (not supported). 206 * @flag: 0 - Call from secure source. 207 * 1 - Call from non-secure source. 208 * 209 * Return: Returns status, either success or error+reason. 210 * 211 */ 212 enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack, 213 uint32_t latency, uint32_t state, 214 uint32_t flag) 215 { 216 uint32_t payload[PAYLOAD_ARG_CNT]; 217 218 /* Send request to the PMU */ 219 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_REQ_SUSPEND, target, 220 latency, state); 221 if (ack == IPI_BLOCKING) { 222 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 223 } else { 224 return pm_ipi_send(primary_proc, payload); 225 } 226 } 227 228 /** 229 * pm_req_wakeup() - PM call for processor to wake up selected processor 230 * or subsystem. 231 * @target: Device ID of the processor or subsystem to wake up. 232 * @set_address: Resume address presence indicator. 233 * 1 - resume address specified, 0 - otherwise. 234 * @address: Resume address. 235 * @ack: Flag to specify whether acknowledge requested. 236 * @flag: 0 - Call from secure source. 237 * 1 - Call from non-secure source. 238 * 239 * This API function is either used to power up another APU core for SMP 240 * (by PSCI) or to power up an entirely different PU or subsystem, such 241 * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be 242 * automatically set by PMC. 243 * 244 * Return: Returns status, either success or error+reason. 245 * 246 */ 247 enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address, 248 uintptr_t address, uint8_t ack, uint32_t flag) 249 { 250 uint32_t payload[PAYLOAD_ARG_CNT]; 251 252 /* Send request to the PMC to perform the wake of the PU */ 253 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REQ_WAKEUP, target, 254 set_address, address, ack); 255 256 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 257 } 258 259 /** 260 * pm_get_callbackdata() - Read from IPI response buffer. 261 * @data: array of PAYLOAD_ARG_CNT elements. 262 * @count: Number of values to return. 263 * @flag: 0 - Call from secure source. 264 * 1 - Call from non-secure source. 265 * @ack: 0 - Do not ack IPI after reading payload. 266 * 1 - Ack IPI after reading payload. 267 * 268 * Read value from ipi buffer response buffer. 269 * Return: Returns status, either success or error. 270 * 271 */ 272 enum pm_ret_status pm_get_callbackdata(uint32_t *data, size_t count, uint32_t flag, uint32_t ack) 273 { 274 enum pm_ret_status ret = PM_RET_SUCCESS; 275 /* Return if interrupt is not from PMU */ 276 if (pm_ipi_irq_status(primary_proc) == 0) { 277 return ret; 278 } 279 280 ret = pm_ipi_buff_read_callb(data, count); 281 282 if (ack != 0U) { 283 pm_ipi_irq_clear(primary_proc); 284 } 285 286 return ret; 287 } 288 289 /** 290 * pm_pll_set_param() - Set PLL parameter. 291 * @clk_id: PLL clock ID. 292 * @param: PLL parameter ID. 293 * @value: Value to set for PLL parameter. 294 * @flag: 0 - Call from secure source. 295 * 1 - Call from non-secure source. 296 * 297 * This API is deprecated and maintained here for backward compatibility. 298 * New use of this API should be avoided for versal platform. 299 * This API and its use cases will be removed for versal platform. 300 * 301 * Return: Returns status, either success or error+reason. 302 * 303 */ 304 enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param, 305 uint32_t value, uint32_t flag) 306 { 307 uint32_t payload[PAYLOAD_ARG_CNT]; 308 309 /* Send request to the PMC */ 310 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_PARAMETER, 311 clk_id, param, value); 312 313 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 314 } 315 316 /** 317 * pm_pll_get_param() - Get PLL parameter value. 318 * @clk_id: PLL clock ID. 319 * @param: PLL parameter ID. 320 * @value: Buffer to store PLL parameter value. 321 * @flag: 0 - Call from secure source. 322 * 1 - Call from non-secure source. 323 * 324 * This API is deprecated and maintained here for backward compatibility. 325 * New use of this API should be avoided for versal platform. 326 * This API and its use cases will be removed for versal platform. 327 * 328 * Return: Returns status, either success or error+reason. 329 * 330 */ 331 enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param, 332 uint32_t *value, uint32_t flag) 333 { 334 uint32_t payload[PAYLOAD_ARG_CNT]; 335 336 /* Send request to the PMC */ 337 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_PARAMETER, 338 clk_id, param); 339 340 return pm_ipi_send_sync(primary_proc, payload, value, 1); 341 } 342 343 /** 344 * pm_pll_set_mode() - Set PLL mode. 345 * @clk_id: PLL clock ID. 346 * @mode: PLL mode. 347 * @flag: 0 - Call from secure source. 348 * 1 - Call from non-secure source. 349 * 350 * This API is deprecated and maintained here for backward compatibility. 351 * New use of this API should be avoided for versal platform. 352 * This API and its use cases will be removed for versal platform. 353 * 354 * Return: Returns status, either success or error+reason. 355 * 356 */ 357 enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode, 358 uint32_t flag) 359 { 360 uint32_t payload[PAYLOAD_ARG_CNT]; 361 362 /* Send request to the PMC */ 363 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_PLL_SET_MODE, 364 clk_id, mode); 365 366 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 367 } 368 369 /** 370 * pm_pll_get_mode() - Get PLL mode. 371 * @clk_id: PLL clock ID. 372 * @mode: Buffer to store PLL mode. 373 * @flag: 0 - Call from secure source. 374 * 1 - Call from non-secure source. 375 * 376 * This API is deprecated and maintained here for backward compatibility. 377 * New use of this API should be avoided for versal platform. 378 * This API and its use cases will be removed for versal platform. 379 * 380 * Return: Returns status, either success or error+reason. 381 * 382 */ 383 enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode, 384 uint32_t flag) 385 { 386 uint32_t payload[PAYLOAD_ARG_CNT]; 387 388 /* Send request to the PMC */ 389 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, PM_PLL_GET_MODE, 390 clk_id); 391 392 return pm_ipi_send_sync(primary_proc, payload, mode, 1); 393 } 394 395 /** 396 * pm_force_powerdown() - PM call to request for another PU or subsystem to 397 * be powered down forcefully. 398 * @target: Device ID of the PU node to be forced powered down. 399 * @ack: Flag to specify whether acknowledge is requested 400 * @flag: 0 - Call from secure source 401 * 1 - Call from non-secure source 402 * 403 * Return: Returns status, either success or error+reason. 404 * 405 */ 406 enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack, 407 uint32_t flag) 408 { 409 uint32_t payload[PAYLOAD_ARG_CNT]; 410 411 /* Send request to the PMC */ 412 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_FORCE_POWERDOWN, 413 target, ack); 414 415 if (ack == IPI_BLOCKING) { 416 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 417 } else { 418 return pm_ipi_send(primary_proc, payload); 419 } 420 } 421 422 /** 423 * pm_system_shutdown() - PM call to request a system shutdown or restart. 424 * @type: Shutdown or restart? 0=shutdown, 1=restart, 2=setscope. 425 * @subtype: Scope: 0=APU-subsystem, 1=PS, 2=system. 426 * @flag: 0 - Call from secure source. 427 * 1 - Call from non-secure source. 428 * 429 * Return: Returns status, either success or error+reason. 430 * 431 */ 432 enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype, 433 uint32_t flag) 434 { 435 uint32_t payload[PAYLOAD_ARG_CNT]; 436 437 if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) { 438 /* Setting scope for subsequent PSCI reboot or shutdown */ 439 pm_shutdown_scope = subtype; 440 return PM_RET_SUCCESS; 441 } 442 443 /* Send request to the PMC */ 444 PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, flag, PM_SYSTEM_SHUTDOWN, 445 type, subtype); 446 447 return pm_ipi_send_non_blocking(primary_proc, payload); 448 } 449 450 /** 451 * pm_query_data() - PM API for querying firmware data. 452 * @qid: The type of data to query. 453 * @arg1: Argument 1 to requested query data call. 454 * @arg2: Argument 2 to requested query data call. 455 * @arg3: Argument 3 to requested query data call. 456 * @data: Returned output data. 457 * @flag: 0 - Call from secure source. 458 * 1 - Call from non-secure source. 459 * 460 * This API is deprecated and maintained here for backward compatibility. 461 * New use of this API should be avoided for versal platform. 462 * This API and its use cases will be removed for versal platform. 463 * 464 * Return: 0 if success else non-zero error code of type 465 * enum pm_ret_status. 466 * 467 */ 468 enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, 469 uint32_t arg3, uint32_t *data, uint32_t flag) 470 { 471 uint32_t ret; 472 uint32_t version[PAYLOAD_ARG_CNT] = {0}; 473 uint32_t payload[PAYLOAD_ARG_CNT]; 474 uint32_t fw_api_version; 475 476 /* Send request to the PMC */ 477 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_QUERY_DATA, qid, 478 arg1, arg2, arg3); 479 480 ret = pm_feature_check((uint32_t)PM_QUERY_DATA, &version[0], flag); 481 if (ret == PM_RET_SUCCESS) { 482 fw_api_version = version[0] & 0xFFFFU; 483 if ((fw_api_version == 2U) && 484 ((qid == XPM_QID_CLOCK_GET_NAME) || 485 (qid == XPM_QID_PINCTRL_GET_FUNCTION_NAME))) { 486 ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT); 487 if (ret == PM_RET_SUCCESS) { 488 ret = data[0]; 489 data[0] = data[1]; 490 data[1] = data[2]; 491 data[2] = data[3]; 492 } 493 } else { 494 ret = pm_ipi_send_sync(primary_proc, payload, data, PAYLOAD_ARG_CNT); 495 } 496 } 497 return ret; 498 } 499 /** 500 * pm_api_ioctl() - PM IOCTL API for device control and configs. 501 * @device_id: Device ID. 502 * @ioctl_id: ID of the requested IOCTL. 503 * @arg1: Argument 1 to requested IOCTL call. 504 * @arg2: Argument 2 to requested IOCTL call. 505 * @arg3: Argument 3 to requested IOCTL call. 506 * @value: Returned output value. 507 * @flag: 0 - Call from secure source. 508 * 1 - Call from non-secure source. 509 * 510 * This API is deprecated and maintained here for backward compatibility. 511 * New use of this API should be avoided for versal platform. 512 * This API and its use cases will be removed for versal platform. 513 * 514 * This function calls IOCTL to firmware for device control and configuration. 515 * 516 * Return: Returns status, either 0 on success or non-zero error code 517 * of type enum pm_ret_status. 518 * 519 */ 520 enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id, 521 uint32_t arg1, uint32_t arg2, uint32_t arg3, 522 uint32_t *value, uint32_t flag) 523 { 524 enum pm_ret_status ret; 525 526 switch (ioctl_id) { 527 case IOCTL_SET_PLL_FRAC_MODE: 528 ret = pm_pll_set_mode(arg1, arg2, flag); 529 break; 530 case IOCTL_GET_PLL_FRAC_MODE: 531 ret = pm_pll_get_mode(arg1, value, flag); 532 break; 533 case IOCTL_SET_PLL_FRAC_DATA: 534 ret = pm_pll_set_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, arg2, flag); 535 break; 536 case IOCTL_GET_PLL_FRAC_DATA: 537 ret = pm_pll_get_param(arg1, (uint32_t)PM_PLL_PARAM_DATA, value, flag); 538 break; 539 case IOCTL_SET_SGI: 540 /* Get the sgi number */ 541 ret = pm_register_sgi(arg1, arg2); 542 if (ret != 0) { 543 return PM_RET_ERROR_ARGS; 544 } 545 ret = PM_RET_SUCCESS; 546 break; 547 default: 548 return PM_RET_ERROR_NOTSUPPORTED; 549 } 550 551 return ret; 552 } 553 554 /** 555 * pm_set_wakeup_source() - PM call to specify the wakeup source while 556 * suspended. 557 * @target: Device id of the targeted PU or subsystem 558 * @wkup_device: Device id of the wakeup peripheral 559 * @enable: Enable or disable the specified peripheral as wake source 560 * @flag: 0 - Call from secure source 561 * 1 - Call from non-secure source 562 * 563 * Return: Returns status, either success or error+reason. 564 * 565 */ 566 enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device, 567 uint8_t enable, uint32_t flag) 568 { 569 uint32_t payload[PAYLOAD_ARG_CNT]; 570 571 PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, flag, PM_SET_WAKEUP_SOURCE, 572 target, wkup_device, enable); 573 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 574 } 575 576 /** 577 * pm_feature_check() - Returns the supported API version if supported. 578 * @api_id: API ID to check. 579 * @flag: 0 - Call from secure source. 580 * 1 - Call from non-secure source. 581 * @ret_payload: pointer to array of PAYLOAD_ARG_CNT number of 582 * words Returned supported API version and bitmasks 583 * for IOCTL and QUERY ID 584 * 585 * Return: Returns status, either success or error+reason. 586 * 587 */ 588 enum pm_ret_status pm_feature_check(uint32_t api_id, uint32_t *ret_payload, 589 uint32_t flag) 590 { 591 uint32_t payload[PAYLOAD_ARG_CNT]; 592 uint32_t module_id; 593 594 /* Return version of API which are implemented in TF-A only */ 595 switch (api_id) { 596 case PM_GET_CALLBACK_DATA: 597 case PM_GET_TRUSTZONE_VERSION: 598 ret_payload[0] = PM_API_VERSION_2; 599 return PM_RET_SUCCESS; 600 case TF_A_PM_REGISTER_SGI: 601 ret_payload[0] = PM_API_BASE_VERSION; 602 return PM_RET_SUCCESS; 603 default: 604 break; 605 } 606 607 module_id = (api_id & MODULE_ID_MASK) >> 8U; 608 609 /* 610 * feature check should be done only for LIBPM module 611 * If module_id is 0, then we consider it LIBPM module as default id 612 */ 613 if ((module_id > 0) && (module_id != LIBPM_MODULE_ID)) { 614 return PM_RET_SUCCESS; 615 } 616 617 PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag, 618 PM_FEATURE_CHECK, api_id); 619 return pm_ipi_send_sync(primary_proc, payload, ret_payload, PAYLOAD_ARG_CNT); 620 } 621 622 /** 623 * pm_load_pdi() - Load the PDI. This function provides support to load 624 * PDI from linux. 625 * 626 * @src: Source device of pdi(DDR, OCM, SD etc). 627 * @address_low: lower 32-bit Linear memory space address. 628 * @address_high: higher 32-bit Linear memory space address. 629 * @flag: 0 - Call from secure source. 630 * 1 - Call from non-secure source. 631 * 632 * Return: Returns status, either success or error+reason. 633 * 634 */ 635 enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low, 636 uint32_t address_high, uint32_t flag) 637 { 638 uint32_t payload[PAYLOAD_ARG_CNT]; 639 640 /* Send request to the PMU */ 641 PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, flag, PM_LOAD_PDI, src, 642 address_high, address_low); 643 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 644 } 645 646 /** 647 * pm_register_notifier() - PM call to register a subsystem to be notified 648 * about the device event. 649 * @device_id: Device ID for the Node to which the event is related. 650 * @event: Event in question. 651 * @wake: Wake subsystem upon capturing the event if value 1. 652 * @enable: Enable the registration for value 1, disable for value 0. 653 * @flag: 0 - Call from secure source. 654 * 1 - Call from non-secure source. 655 * 656 * Return: Returns status, either success or error+reason. 657 * 658 */ 659 enum pm_ret_status pm_register_notifier(uint32_t device_id, uint32_t event, 660 uint32_t wake, uint32_t enable, 661 uint32_t flag) 662 { 663 uint32_t payload[PAYLOAD_ARG_CNT]; 664 665 /* Send request to the PMC */ 666 PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, flag, PM_REGISTER_NOTIFIER, 667 device_id, event, wake, enable); 668 669 return pm_ipi_send_sync(primary_proc, payload, NULL, 0); 670 } 671 672 /** 673 * pm_get_chipid() - Read silicon ID registers. 674 * @value: Buffer for two 32bit words. 675 * 676 * Return: Returns status, either success or error+reason and, 677 * optionally, @value. 678 */ 679 enum pm_ret_status pm_get_chipid(uint32_t *value) 680 { 681 uint32_t payload[PAYLOAD_ARG_CNT]; 682 683 PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, SECURE_FLAG, PM_GET_CHIPID); 684 685 return pm_ipi_send_sync(primary_proc, payload, value, 2); 686 } 687