1 /* 2 * Texas Instruments System Control Interface Driver 3 * Based on Linux and U-Boot implementation 4 * 5 * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/ 6 * 7 * SPDX-License-Identifier: BSD-3-Clause 8 */ 9 10 #include <errno.h> 11 #include <stdbool.h> 12 #include <stddef.h> 13 #include <string.h> 14 15 #include <platform_def.h> 16 #include <lib/bakery_lock.h> 17 18 #include <common/debug.h> 19 #include <ti_sci_transport.h> 20 21 #include "ti_sci_protocol.h" 22 #include "ti_sci.h" 23 24 #if USE_COHERENT_MEM 25 __section(".tzfw_coherent_mem") 26 #endif 27 static uint8_t message_sequence; 28 29 DEFINE_BAKERY_LOCK(ti_sci_xfer_lock); 30 31 /** 32 * struct ti_sci_xfer - Structure representing a message flow 33 * @tx_message: Transmit message 34 * @rx_message: Receive message 35 */ 36 struct ti_sci_xfer { 37 struct k3_sec_proxy_msg tx_message; 38 struct k3_sec_proxy_msg rx_message; 39 }; 40 41 /** 42 * ti_sci_setup_one_xfer() - Setup one message type 43 * 44 * @msg_type: Message type 45 * @msg_flags: Flag to set for the message 46 * @tx_buf: Buffer to be sent to mailbox channel 47 * @tx_message_size: transmit message size 48 * @rx_buf: Buffer to be received from mailbox channel 49 * @rx_message_size: receive message size 50 * 51 * Helper function which is used by various command functions that are 52 * exposed to clients of this driver for allocating a message traffic event. 53 * 54 * Return: 0 if all goes well, else appropriate error message 55 */ 56 static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags, 57 void *tx_buf, 58 size_t tx_message_size, 59 void *rx_buf, 60 size_t rx_message_size, 61 struct ti_sci_xfer *xfer) 62 { 63 struct ti_sci_msg_hdr *hdr; 64 65 /* Ensure we have sane transfer sizes */ 66 if (rx_message_size > TI_SCI_MAX_MESSAGE_SIZE || 67 tx_message_size > TI_SCI_MAX_MESSAGE_SIZE || 68 tx_message_size < sizeof(*hdr)) 69 return -ERANGE; 70 71 hdr = (struct ti_sci_msg_hdr *)tx_buf; 72 hdr->seq = ++message_sequence; 73 hdr->type = msg_type; 74 hdr->host = TI_SCI_HOST_ID; 75 hdr->flags = msg_flags; 76 /* Request a response if rx_message_size is non-zero */ 77 if (rx_message_size != 0U) { 78 hdr->flags |= TI_SCI_FLAG_REQ_ACK_ON_PROCESSED; 79 } 80 81 xfer->tx_message.buf = tx_buf; 82 xfer->tx_message.len = tx_message_size; 83 84 xfer->rx_message.buf = rx_buf; 85 xfer->rx_message.len = rx_message_size; 86 87 return 0; 88 } 89 90 /** 91 * ti_sci_get_response() - Receive response from mailbox channel 92 * 93 * @xfer: Transfer to initiate and wait for response 94 * @chan: Channel to receive the response 95 * 96 * Return: 0 if all goes well, else appropriate error message 97 */ 98 static int ti_sci_get_response(struct k3_sec_proxy_msg *msg, 99 enum k3_sec_proxy_chan_id chan) 100 { 101 struct ti_sci_msg_hdr *hdr; 102 unsigned int retry = 5; 103 int ret; 104 105 for (; retry > 0; retry--) { 106 /* Receive the response */ 107 ret = k3_sec_proxy_recv(chan, msg); 108 if (ret) { 109 ERROR("Message receive failed (%d)\n", ret); 110 return ret; 111 } 112 113 /* msg is updated by Secure Proxy driver */ 114 hdr = (struct ti_sci_msg_hdr *)msg->buf; 115 116 /* Sanity check for message response */ 117 if (hdr->seq == message_sequence) 118 break; 119 else 120 WARN("Message with sequence ID %u is not expected\n", hdr->seq); 121 } 122 if (!retry) { 123 ERROR("Timed out waiting for message\n"); 124 return -EINVAL; 125 } 126 127 if (msg->len > TI_SCI_MAX_MESSAGE_SIZE) { 128 ERROR("Unable to handle %lu xfer (max %d)\n", 129 msg->len, TI_SCI_MAX_MESSAGE_SIZE); 130 return -EINVAL; 131 } 132 133 if (!(hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK)) 134 return -ENODEV; 135 136 return 0; 137 } 138 139 /** 140 * ti_sci_do_xfer() - Do one transfer 141 * 142 * @xfer: Transfer to initiate and wait for response 143 * 144 * Return: 0 if all goes well, else appropriate error message 145 */ 146 static int ti_sci_do_xfer(struct ti_sci_xfer *xfer) 147 { 148 struct k3_sec_proxy_msg *tx_msg = &xfer->tx_message; 149 struct k3_sec_proxy_msg *rx_msg = &xfer->rx_message; 150 int ret; 151 152 bakery_lock_get(&ti_sci_xfer_lock); 153 154 /* Clear any spurious messages in receive queue */ 155 ret = k3_sec_proxy_clear_rx_thread(SP_RESPONSE); 156 if (ret) { 157 ERROR("Could not clear response queue (%d)\n", ret); 158 goto unlock; 159 } 160 161 /* Send the message */ 162 ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, tx_msg); 163 if (ret) { 164 ERROR("Message sending failed (%d)\n", ret); 165 goto unlock; 166 } 167 168 /* Get the response if requested */ 169 if (rx_msg->len != 0U) { 170 ret = ti_sci_get_response(rx_msg, SP_RESPONSE); 171 if (ret != 0U) { 172 ERROR("Failed to get response (%d)\n", ret); 173 goto unlock; 174 } 175 } 176 177 unlock: 178 bakery_lock_release(&ti_sci_xfer_lock); 179 180 return ret; 181 } 182 183 /** 184 * ti_sci_get_revision() - Get the revision of the SCI entity 185 * 186 * Updates the SCI information in the internal data structure. 187 * 188 * @version: Structure containing the version info 189 * 190 * Return: 0 if all goes well, else appropriate error message 191 */ 192 int ti_sci_get_revision(struct ti_sci_msg_version *version) 193 { 194 struct ti_sci_msg_resp_version rev_info; 195 struct ti_sci_msg_hdr hdr; 196 struct ti_sci_xfer xfer; 197 int ret; 198 199 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_VERSION, 0x0, 200 &hdr, sizeof(hdr), 201 &rev_info, sizeof(rev_info), 202 &xfer); 203 if (ret) { 204 ERROR("Message alloc failed (%d)\n", ret); 205 return ret; 206 } 207 208 ret = ti_sci_do_xfer(&xfer); 209 if (ret) { 210 ERROR("Transfer send failed (%d)\n", ret); 211 return ret; 212 } 213 214 memcpy(version->firmware_description, rev_info.firmware_description, 215 sizeof(rev_info.firmware_description)); 216 version->abi_major = rev_info.abi_major; 217 version->abi_minor = rev_info.abi_minor; 218 version->firmware_revision = rev_info.firmware_revision; 219 version->sub_version = rev_info.sub_version; 220 version->patch_version = rev_info.patch_version; 221 222 return 0; 223 } 224 225 /** 226 * ti_sci_query_fw_caps() - Get the FW/SoC capabilities 227 * @handle: Pointer to TI SCI handle 228 * @fw_caps: Each bit in fw_caps indicating one FW/SOC capability 229 * 230 * Return: 0 if all went well, else returns appropriate error value. 231 */ 232 int ti_sci_query_fw_caps(uint64_t *fw_caps) 233 { 234 struct ti_sci_msg_hdr req; 235 struct ti_sci_msg_resp_query_fw_caps resp; 236 237 struct ti_sci_xfer xfer; 238 int ret; 239 240 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_FW_CAPS, 0, 241 &req, sizeof(req), 242 &resp, sizeof(resp), 243 &xfer); 244 if (ret != 0U) { 245 ERROR("Message alloc failed (%d)\n", ret); 246 return ret; 247 } 248 249 ret = ti_sci_do_xfer(&xfer); 250 if (ret != 0U) { 251 ERROR("Transfer send failed (%d)\n", ret); 252 return ret; 253 } 254 255 if (fw_caps) 256 *fw_caps = resp.fw_caps; 257 258 return 0; 259 } 260 261 /** 262 * ti_sci_device_set_state() - Set device state 263 * 264 * @id: Device identifier 265 * @flags: flags to setup for the device 266 * @state: State to move the device to 267 * 268 * Return: 0 if all goes well, else appropriate error message 269 */ 270 static int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state) 271 { 272 struct ti_sci_msg_req_set_device_state req; 273 struct ti_sci_msg_hdr resp; 274 275 struct ti_sci_xfer xfer; 276 int ret; 277 278 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, flags, 279 &req, sizeof(req), 280 &resp, sizeof(resp), 281 &xfer); 282 if (ret) { 283 ERROR("Message alloc failed (%d)\n", ret); 284 return ret; 285 } 286 287 req.id = id; 288 req.state = state; 289 290 ret = ti_sci_do_xfer(&xfer); 291 if (ret) { 292 ERROR("Transfer send failed (%d)\n", ret); 293 return ret; 294 } 295 296 return 0; 297 } 298 299 /** 300 * ti_sci_device_get_state() - Get device state 301 * 302 * @id: Device Identifier 303 * @clcnt: Pointer to Context Loss Count 304 * @resets: pointer to resets 305 * @p_state: pointer to p_state 306 * @c_state: pointer to c_state 307 * 308 * Return: 0 if all goes well, else appropriate error message 309 */ 310 static int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, 311 uint32_t *resets, uint8_t *p_state, 312 uint8_t *c_state) 313 { 314 struct ti_sci_msg_req_get_device_state req; 315 struct ti_sci_msg_resp_get_device_state resp; 316 317 struct ti_sci_xfer xfer; 318 int ret; 319 320 if (!clcnt && !resets && !p_state && !c_state) 321 return -EINVAL; 322 323 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0, 324 &req, sizeof(req), 325 &resp, sizeof(resp), 326 &xfer); 327 if (ret) { 328 ERROR("Message alloc failed (%d)\n", ret); 329 return ret; 330 } 331 332 req.id = id; 333 334 ret = ti_sci_do_xfer(&xfer); 335 if (ret) { 336 ERROR("Transfer send failed (%d)\n", ret); 337 return ret; 338 } 339 340 if (clcnt) 341 *clcnt = resp.context_loss_count; 342 if (resets) 343 *resets = resp.resets; 344 if (p_state) 345 *p_state = resp.programmed_state; 346 if (c_state) 347 *c_state = resp.current_state; 348 349 return 0; 350 } 351 352 /** 353 * ti_sci_device_get() - Request for device managed by TISCI 354 * 355 * @id: Device Identifier 356 * 357 * Request for the device - NOTE: the client MUST maintain integrity of 358 * usage count by balancing get_device with put_device. No refcounting is 359 * managed by driver for that purpose. 360 * 361 * Return: 0 if all goes well, else appropriate error message 362 */ 363 int ti_sci_device_get(uint32_t id) 364 { 365 return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_ON); 366 } 367 368 /** 369 * ti_sci_device_get_exclusive() - Exclusive request for device managed by TISCI 370 * 371 * @id: Device Identifier 372 * 373 * Request for the device - NOTE: the client MUST maintain integrity of 374 * usage count by balancing get_device with put_device. No refcounting is 375 * managed by driver for that purpose. 376 * 377 * NOTE: This _exclusive version of the get API is for exclusive access to the 378 * device. Any other host in the system will fail to get this device after this 379 * call until exclusive access is released with device_put or a non-exclusive 380 * set call. 381 * 382 * Return: 0 if all goes well, else appropriate error message 383 */ 384 int ti_sci_device_get_exclusive(uint32_t id) 385 { 386 return ti_sci_device_set_state(id, 387 MSG_FLAG_DEVICE_EXCLUSIVE, 388 MSG_DEVICE_SW_STATE_ON); 389 } 390 391 /** 392 * ti_sci_device_idle() - Idle a device managed by TISCI 393 * 394 * @id: Device Identifier 395 * 396 * Request for the device - NOTE: the client MUST maintain integrity of 397 * usage count by balancing get_device with put_device. No refcounting is 398 * managed by driver for that purpose. 399 * 400 * Return: 0 if all goes well, else appropriate error message 401 */ 402 int ti_sci_device_idle(uint32_t id) 403 { 404 return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_RETENTION); 405 } 406 407 /** 408 * ti_sci_device_idle_exclusive() - Exclusive idle a device managed by TISCI 409 * 410 * @id: Device Identifier 411 * 412 * Request for the device - NOTE: the client MUST maintain integrity of 413 * usage count by balancing get_device with put_device. No refcounting is 414 * managed by driver for that purpose. 415 * 416 * NOTE: This _exclusive version of the idle API is for exclusive access to 417 * the device. Any other host in the system will fail to get this device after 418 * this call until exclusive access is released with device_put or a 419 * non-exclusive set call. 420 * 421 * Return: 0 if all goes well, else appropriate error message 422 */ 423 int ti_sci_device_idle_exclusive(uint32_t id) 424 { 425 return ti_sci_device_set_state(id, 426 MSG_FLAG_DEVICE_EXCLUSIVE, 427 MSG_DEVICE_SW_STATE_RETENTION); 428 } 429 430 /** 431 * ti_sci_device_put() - Release a device managed by TISCI 432 * 433 * @id: Device Identifier 434 * 435 * Request for the device - NOTE: the client MUST maintain integrity of 436 * usage count by balancing get_device with put_device. No refcounting is 437 * managed by driver for that purpose. 438 * 439 * Return: 0 if all goes well, else appropriate error message 440 */ 441 int ti_sci_device_put(uint32_t id) 442 { 443 return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_AUTO_OFF); 444 } 445 446 /** 447 * ti_sci_device_put_no_wait() - Release a device without requesting or waiting 448 * for a response. 449 * 450 * @id: Device Identifier 451 * 452 * Request for the device - NOTE: the client MUST maintain integrity of 453 * usage count by balancing get_device with put_device. No refcounting is 454 * managed by driver for that purpose. 455 * 456 * Return: 0 if all goes well, else appropriate error message 457 */ 458 int ti_sci_device_put_no_wait(uint32_t id) 459 { 460 struct ti_sci_msg_req_set_device_state req; 461 struct ti_sci_xfer xfer; 462 int ret; 463 464 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE, 0, 465 &req, sizeof(req), 466 NULL, 0, 467 &xfer); 468 if (ret != 0U) { 469 ERROR("Message alloc failed (%d)\n", ret); 470 return ret; 471 } 472 473 req.id = id; 474 req.state = MSG_DEVICE_SW_STATE_AUTO_OFF; 475 476 ret = ti_sci_do_xfer(&xfer); 477 if (ret != 0U) { 478 ERROR("Transfer send failed (%d)\n", ret); 479 return ret; 480 } 481 482 return 0; 483 } 484 485 /** 486 * ti_sci_device_is_valid() - Is the device valid 487 * 488 * @id: Device Identifier 489 * 490 * Return: 0 if all goes well and the device ID is valid, else return 491 * appropriate error 492 */ 493 int ti_sci_device_is_valid(uint32_t id) 494 { 495 uint8_t unused; 496 497 /* check the device state which will also tell us if the ID is valid */ 498 return ti_sci_device_get_state(id, NULL, NULL, NULL, &unused); 499 } 500 501 /** 502 * ti_sci_device_get_clcnt() - Get context loss counter 503 * 504 * @id: Device Identifier 505 * @count: Pointer to Context Loss counter to populate 506 * 507 * Return: 0 if all goes well, else appropriate error message 508 */ 509 int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count) 510 { 511 return ti_sci_device_get_state(id, count, NULL, NULL, NULL); 512 } 513 514 /** 515 * ti_sci_device_is_idle() - Check if the device is requested to be idle 516 * 517 * @id: Device Identifier 518 * @r_state: true if requested to be idle 519 * 520 * Return: 0 if all goes well, else appropriate error message 521 */ 522 int ti_sci_device_is_idle(uint32_t id, bool *r_state) 523 { 524 int ret; 525 uint8_t state; 526 527 if (!r_state) 528 return -EINVAL; 529 530 ret = ti_sci_device_get_state(id, NULL, NULL, &state, NULL); 531 if (ret) 532 return ret; 533 534 *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION); 535 536 return 0; 537 } 538 539 /** 540 * ti_sci_device_is_stop() - Check if the device is requested to be stopped 541 * 542 * @id: Device Identifier 543 * @r_state: true if requested to be stopped 544 * @curr_state: true if currently stopped 545 * 546 * Return: 0 if all goes well, else appropriate error message 547 */ 548 int ti_sci_device_is_stop(uint32_t id, bool *r_state, bool *curr_state) 549 { 550 int ret; 551 uint8_t p_state, c_state; 552 553 if (!r_state && !curr_state) 554 return -EINVAL; 555 556 ret = ti_sci_device_get_state(id, NULL, NULL, &p_state, &c_state); 557 if (ret) 558 return ret; 559 560 if (r_state) 561 *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF); 562 if (curr_state) 563 *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF); 564 565 return 0; 566 } 567 568 /** 569 * ti_sci_device_is_on() - Check if the device is requested to be ON 570 * 571 * @id: Device Identifier 572 * @r_state: true if requested to be ON 573 * @curr_state: true if currently ON and active 574 * 575 * Return: 0 if all goes well, else appropriate error message 576 */ 577 int ti_sci_device_is_on(uint32_t id, bool *r_state, bool *curr_state) 578 { 579 int ret; 580 uint8_t p_state, c_state; 581 582 if (!r_state && !curr_state) 583 return -EINVAL; 584 585 ret = 586 ti_sci_device_get_state(id, NULL, NULL, &p_state, &c_state); 587 if (ret) 588 return ret; 589 590 if (r_state) 591 *r_state = (p_state == MSG_DEVICE_SW_STATE_ON); 592 if (curr_state) 593 *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON); 594 595 return 0; 596 } 597 598 /** 599 * ti_sci_device_is_trans() - Check if the device is currently transitioning 600 * 601 * @id: Device Identifier 602 * @curr_state: true if currently transitioning 603 * 604 * Return: 0 if all goes well, else appropriate error message 605 */ 606 int ti_sci_device_is_trans(uint32_t id, bool *curr_state) 607 { 608 int ret; 609 uint8_t state; 610 611 if (!curr_state) 612 return -EINVAL; 613 614 ret = ti_sci_device_get_state(id, NULL, NULL, NULL, &state); 615 if (ret) 616 return ret; 617 618 *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS); 619 620 return 0; 621 } 622 623 /** 624 * ti_sci_device_set_resets() - Set resets for device managed by TISCI 625 * 626 * @id: Device Identifier 627 * @reset_state: Device specific reset bit field 628 * 629 * Return: 0 if all goes well, else appropriate error message 630 */ 631 int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state) 632 { 633 struct ti_sci_msg_req_set_device_resets req; 634 struct ti_sci_msg_hdr resp; 635 636 struct ti_sci_xfer xfer; 637 int ret; 638 639 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_RESETS, 0, 640 &req, sizeof(req), 641 &resp, sizeof(resp), 642 &xfer); 643 if (ret) { 644 ERROR("Message alloc failed (%d)\n", ret); 645 return ret; 646 } 647 648 req.id = id; 649 req.resets = reset_state; 650 651 ret = ti_sci_do_xfer(&xfer); 652 if (ret) { 653 ERROR("Transfer send failed (%d)\n", ret); 654 return ret; 655 } 656 657 return 0; 658 } 659 660 /** 661 * ti_sci_device_get_resets() - Get reset state for device managed by TISCI 662 * 663 * @id: Device Identifier 664 * @reset_state: Pointer to reset state to populate 665 * 666 * Return: 0 if all goes well, else appropriate error message 667 */ 668 int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state) 669 { 670 return ti_sci_device_get_state(id, NULL, reset_state, NULL, NULL); 671 } 672 673 /** 674 * ti_sci_clock_set_state() - Set clock state helper 675 * 676 * @dev_id: Device identifier this request is for 677 * @clk_id: Clock identifier for the device for this request, 678 * Each device has its own set of clock inputs, This indexes 679 * which clock input to modify 680 * @flags: Header flags as needed 681 * @state: State to request for the clock 682 * 683 * Return: 0 if all goes well, else appropriate error message 684 */ 685 int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id, 686 uint32_t flags, uint8_t state) 687 { 688 struct ti_sci_msg_req_set_clock_state req; 689 struct ti_sci_msg_hdr resp; 690 691 struct ti_sci_xfer xfer; 692 int ret; 693 694 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_STATE, flags, 695 &req, sizeof(req), 696 &resp, sizeof(resp), 697 &xfer); 698 if (ret) { 699 ERROR("Message alloc failed (%d)\n", ret); 700 return ret; 701 } 702 703 req.dev_id = dev_id; 704 req.clk_id = clk_id; 705 req.request_state = state; 706 707 ret = ti_sci_do_xfer(&xfer); 708 if (ret) { 709 ERROR("Transfer send failed (%d)\n", ret); 710 return ret; 711 } 712 713 return 0; 714 } 715 716 /** 717 * ti_sci_clock_get_state() - Get clock state helper 718 * 719 * @dev_id: Device identifier this request is for 720 * @clk_id: Clock identifier for the device for this request. 721 * Each device has its own set of clock inputs. This indexes 722 * which clock input to modify. 723 * @programmed_state: State requested for clock to move to 724 * @current_state: State that the clock is currently in 725 * 726 * Return: 0 if all goes well, else appropriate error message 727 */ 728 int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id, 729 uint8_t *programmed_state, 730 uint8_t *current_state) 731 { 732 struct ti_sci_msg_req_get_clock_state req; 733 struct ti_sci_msg_resp_get_clock_state resp; 734 735 struct ti_sci_xfer xfer; 736 int ret; 737 738 if (!programmed_state && !current_state) 739 return -EINVAL; 740 741 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_STATE, 0, 742 &req, sizeof(req), 743 &resp, sizeof(resp), 744 &xfer); 745 if (ret) { 746 ERROR("Message alloc failed (%d)\n", ret); 747 return ret; 748 } 749 750 req.dev_id = dev_id; 751 req.clk_id = clk_id; 752 753 ret = ti_sci_do_xfer(&xfer); 754 if (ret) { 755 ERROR("Transfer send failed (%d)\n", ret); 756 return ret; 757 } 758 759 if (programmed_state) 760 *programmed_state = resp.programmed_state; 761 if (current_state) 762 *current_state = resp.current_state; 763 764 return 0; 765 } 766 767 /** 768 * ti_sci_clock_get() - Get control of a clock from TI SCI 769 770 * @dev_id: Device identifier this request is for 771 * @clk_id: Clock identifier for the device for this request. 772 * Each device has its own set of clock inputs. This indexes 773 * which clock input to modify. 774 * @needs_ssc: 'true' iff Spread Spectrum clock is desired 775 * @can_change_freq: 'true' iff frequency change is desired 776 * @enable_input_term: 'true' iff input termination is desired 777 * 778 * Return: 0 if all goes well, else appropriate error message 779 */ 780 int ti_sci_clock_get(uint32_t dev_id, uint8_t clk_id, 781 bool needs_ssc, bool can_change_freq, 782 bool enable_input_term) 783 { 784 uint32_t flags = 0; 785 786 flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0; 787 flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0; 788 flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0; 789 790 return ti_sci_clock_set_state(dev_id, clk_id, flags, 791 MSG_CLOCK_SW_STATE_REQ); 792 } 793 794 /** 795 * ti_sci_clock_idle() - Idle a clock which is in our control 796 797 * @dev_id: Device identifier this request is for 798 * @clk_id: Clock identifier for the device for this request. 799 * Each device has its own set of clock inputs. This indexes 800 * which clock input to modify. 801 * 802 * NOTE: This clock must have been requested by get_clock previously. 803 * 804 * Return: 0 if all goes well, else appropriate error message 805 */ 806 int ti_sci_clock_idle(uint32_t dev_id, uint8_t clk_id) 807 { 808 return ti_sci_clock_set_state(dev_id, clk_id, 0, 809 MSG_CLOCK_SW_STATE_UNREQ); 810 } 811 812 /** 813 * ti_sci_clock_put() - Release a clock from our control 814 * 815 * @dev_id: Device identifier this request is for 816 * @clk_id: Clock identifier for the device for this request. 817 * Each device has its own set of clock inputs. This indexes 818 * which clock input to modify. 819 * 820 * NOTE: This clock must have been requested by get_clock previously. 821 * 822 * Return: 0 if all goes well, else appropriate error message 823 */ 824 int ti_sci_clock_put(uint32_t dev_id, uint8_t clk_id) 825 { 826 return ti_sci_clock_set_state(dev_id, clk_id, 0, 827 MSG_CLOCK_SW_STATE_AUTO); 828 } 829 830 /** 831 * ti_sci_clock_is_auto() - Is the clock being auto managed 832 * 833 * @dev_id: Device identifier this request is for 834 * @clk_id: Clock identifier for the device for this request. 835 * Each device has its own set of clock inputs. This indexes 836 * which clock input to modify. 837 * @req_state: state indicating if the clock is auto managed 838 * 839 * Return: 0 if all goes well, else appropriate error message 840 */ 841 int ti_sci_clock_is_auto(uint32_t dev_id, uint8_t clk_id, bool *req_state) 842 { 843 uint8_t state = 0; 844 int ret; 845 846 if (!req_state) 847 return -EINVAL; 848 849 ret = ti_sci_clock_get_state(dev_id, clk_id, &state, NULL); 850 if (ret) 851 return ret; 852 853 *req_state = (state == MSG_CLOCK_SW_STATE_AUTO); 854 855 return 0; 856 } 857 858 /** 859 * ti_sci_clock_is_on() - Is the clock ON 860 * 861 * @dev_id: Device identifier this request is for 862 * @clk_id: Clock identifier for the device for this request. 863 * Each device has its own set of clock inputs. This indexes 864 * which clock input to modify. 865 * @req_state: state indicating if the clock is managed by us and enabled 866 * @curr_state: state indicating if the clock is ready for operation 867 * 868 * Return: 0 if all goes well, else appropriate error message 869 */ 870 int ti_sci_clock_is_on(uint32_t dev_id, uint8_t clk_id, 871 bool *req_state, bool *curr_state) 872 { 873 uint8_t c_state = 0, r_state = 0; 874 int ret; 875 876 if (!req_state && !curr_state) 877 return -EINVAL; 878 879 ret = ti_sci_clock_get_state(dev_id, clk_id, &r_state, &c_state); 880 if (ret) 881 return ret; 882 883 if (req_state) 884 *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ); 885 if (curr_state) 886 *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY); 887 888 return 0; 889 } 890 891 /** 892 * ti_sci_clock_is_off() - Is the clock OFF 893 * 894 * @dev_id: Device identifier this request is for 895 * @clk_id: Clock identifier for the device for this request. 896 * Each device has its own set of clock inputs. This indexes 897 * which clock input to modify. 898 * @req_state: state indicating if the clock is managed by us and disabled 899 * @curr_state: state indicating if the clock is NOT ready for operation 900 * 901 * Return: 0 if all goes well, else appropriate error message 902 */ 903 int ti_sci_clock_is_off(uint32_t dev_id, uint8_t clk_id, 904 bool *req_state, bool *curr_state) 905 { 906 uint8_t c_state = 0, r_state = 0; 907 int ret; 908 909 if (!req_state && !curr_state) 910 return -EINVAL; 911 912 ret = ti_sci_clock_get_state(dev_id, clk_id, &r_state, &c_state); 913 if (ret) 914 return ret; 915 916 if (req_state) 917 *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ); 918 if (curr_state) 919 *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY); 920 921 return 0; 922 } 923 924 /** 925 * ti_sci_clock_set_parent() - Set the clock source of a specific device clock 926 * 927 * @dev_id: Device identifier this request is for 928 * @clk_id: Clock identifier for the device for this request. 929 * Each device has its own set of clock inputs. This indexes 930 * which clock input to modify. 931 * @parent_id: Parent clock identifier to set 932 * 933 * Return: 0 if all goes well, else appropriate error message 934 */ 935 int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id, uint8_t parent_id) 936 { 937 struct ti_sci_msg_req_set_clock_parent req; 938 struct ti_sci_msg_hdr resp; 939 940 struct ti_sci_xfer xfer; 941 int ret; 942 943 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_PARENT, 0, 944 &req, sizeof(req), 945 &resp, sizeof(resp), 946 &xfer); 947 if (ret) { 948 ERROR("Message alloc failed (%d)\n", ret); 949 return ret; 950 } 951 952 req.dev_id = dev_id; 953 req.clk_id = clk_id; 954 req.parent_id = parent_id; 955 956 ret = ti_sci_do_xfer(&xfer); 957 if (ret) { 958 ERROR("Transfer send failed (%d)\n", ret); 959 return ret; 960 } 961 962 return 0; 963 } 964 965 /** 966 * ti_sci_clock_get_parent() - Get current parent clock source 967 * 968 * @dev_id: Device identifier this request is for 969 * @clk_id: Clock identifier for the device for this request. 970 * Each device has its own set of clock inputs. This indexes 971 * which clock input to modify. 972 * @parent_id: Current clock parent 973 * 974 * Return: 0 if all goes well, else appropriate error message 975 */ 976 int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id, uint8_t *parent_id) 977 { 978 struct ti_sci_msg_req_get_clock_parent req; 979 struct ti_sci_msg_resp_get_clock_parent resp; 980 981 struct ti_sci_xfer xfer; 982 int ret; 983 984 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_PARENT, 0, 985 &req, sizeof(req), 986 &resp, sizeof(resp), 987 &xfer); 988 if (ret) { 989 ERROR("Message alloc failed (%d)\n", ret); 990 return ret; 991 } 992 993 req.dev_id = dev_id; 994 req.clk_id = clk_id; 995 996 ret = ti_sci_do_xfer(&xfer); 997 if (ret) { 998 ERROR("Transfer send failed (%d)\n", ret); 999 return ret; 1000 } 1001 1002 *parent_id = resp.parent_id; 1003 1004 return 0; 1005 } 1006 1007 /** 1008 * ti_sci_clock_get_num_parents() - Get num parents of the current clk source 1009 * 1010 * @dev_id: Device identifier this request is for 1011 * @clk_id: Clock identifier for the device for this request. 1012 * Each device has its own set of clock inputs. This indexes 1013 * which clock input to modify. 1014 * @num_parents: Returns he number of parents to the current clock. 1015 * 1016 * Return: 0 if all goes well, else appropriate error message 1017 */ 1018 int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id, 1019 uint8_t *num_parents) 1020 { 1021 struct ti_sci_msg_req_get_clock_num_parents req; 1022 struct ti_sci_msg_resp_get_clock_num_parents resp; 1023 1024 struct ti_sci_xfer xfer; 1025 int ret; 1026 1027 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, 0, 1028 &req, sizeof(req), 1029 &resp, sizeof(resp), 1030 &xfer); 1031 if (ret) { 1032 ERROR("Message alloc failed (%d)\n", ret); 1033 return ret; 1034 } 1035 1036 req.dev_id = dev_id; 1037 req.clk_id = clk_id; 1038 1039 ret = ti_sci_do_xfer(&xfer); 1040 if (ret) { 1041 ERROR("Transfer send failed (%d)\n", ret); 1042 return ret; 1043 } 1044 1045 *num_parents = resp.num_parents; 1046 1047 return 0; 1048 } 1049 1050 /** 1051 * ti_sci_clock_get_match_freq() - Find a good match for frequency 1052 * 1053 * @dev_id: Device identifier this request is for 1054 * @clk_id: Clock identifier for the device for this request. 1055 * Each device has its own set of clock inputs. This indexes 1056 * which clock input to modify. 1057 * @min_freq: The minimum allowable frequency in Hz. This is the minimum 1058 * allowable programmed frequency and does not account for clock 1059 * tolerances and jitter. 1060 * @target_freq: The target clock frequency in Hz. A frequency will be 1061 * processed as close to this target frequency as possible. 1062 * @max_freq: The maximum allowable frequency in Hz. This is the maximum 1063 * allowable programmed frequency and does not account for clock 1064 * tolerances and jitter. 1065 * @match_freq: Frequency match in Hz response. 1066 * 1067 * Return: 0 if all goes well, else appropriate error message 1068 */ 1069 int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id, 1070 uint64_t min_freq, uint64_t target_freq, 1071 uint64_t max_freq, uint64_t *match_freq) 1072 { 1073 struct ti_sci_msg_req_query_clock_freq req; 1074 struct ti_sci_msg_resp_query_clock_freq resp; 1075 1076 struct ti_sci_xfer xfer; 1077 int ret; 1078 1079 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_CLOCK_FREQ, 0, 1080 &req, sizeof(req), 1081 &resp, sizeof(resp), 1082 &xfer); 1083 if (ret) { 1084 ERROR("Message alloc failed (%d)\n", ret); 1085 return ret; 1086 } 1087 1088 req.dev_id = dev_id; 1089 req.clk_id = clk_id; 1090 req.min_freq_hz = min_freq; 1091 req.target_freq_hz = target_freq; 1092 req.max_freq_hz = max_freq; 1093 1094 ret = ti_sci_do_xfer(&xfer); 1095 if (ret) { 1096 ERROR("Transfer send failed (%d)\n", ret); 1097 return ret; 1098 } 1099 1100 *match_freq = resp.freq_hz; 1101 1102 return 0; 1103 } 1104 1105 /** 1106 * ti_sci_clock_set_freq() - Set a frequency for clock 1107 * 1108 * @dev_id: Device identifier this request is for 1109 * @clk_id: Clock identifier for the device for this request. 1110 * Each device has its own set of clock inputs. This indexes 1111 * which clock input to modify. 1112 * @min_freq: The minimum allowable frequency in Hz. This is the minimum 1113 * allowable programmed frequency and does not account for clock 1114 * tolerances and jitter. 1115 * @target_freq: The target clock frequency in Hz. A frequency will be 1116 * processed as close to this target frequency as possible. 1117 * @max_freq: The maximum allowable frequency in Hz. This is the maximum 1118 * allowable programmed frequency and does not account for clock 1119 * tolerances and jitter. 1120 * 1121 * Return: 0 if all goes well, else appropriate error message 1122 */ 1123 int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id, uint64_t min_freq, 1124 uint64_t target_freq, uint64_t max_freq) 1125 { 1126 struct ti_sci_msg_req_set_clock_freq req; 1127 struct ti_sci_msg_hdr resp; 1128 1129 struct ti_sci_xfer xfer; 1130 int ret; 1131 1132 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_FREQ, 0, 1133 &req, sizeof(req), 1134 &resp, sizeof(resp), 1135 &xfer); 1136 if (ret) { 1137 ERROR("Message alloc failed (%d)\n", ret); 1138 return ret; 1139 } 1140 req.dev_id = dev_id; 1141 req.clk_id = clk_id; 1142 req.min_freq_hz = min_freq; 1143 req.target_freq_hz = target_freq; 1144 req.max_freq_hz = max_freq; 1145 1146 ret = ti_sci_do_xfer(&xfer); 1147 if (ret) { 1148 ERROR("Transfer send failed (%d)\n", ret); 1149 return ret; 1150 } 1151 1152 return 0; 1153 } 1154 1155 /** 1156 * ti_sci_clock_get_freq() - Get current frequency 1157 * 1158 * @dev_id: Device identifier this request is for 1159 * @clk_id: Clock identifier for the device for this request. 1160 * Each device has its own set of clock inputs. This indexes 1161 * which clock input to modify. 1162 * @freq: Currently frequency in Hz 1163 * 1164 * Return: 0 if all goes well, else appropriate error message 1165 */ 1166 int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq) 1167 { 1168 struct ti_sci_msg_req_get_clock_freq req; 1169 struct ti_sci_msg_resp_get_clock_freq resp; 1170 1171 struct ti_sci_xfer xfer; 1172 int ret; 1173 1174 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_FREQ, 0, 1175 &req, sizeof(req), 1176 &resp, sizeof(resp), 1177 &xfer); 1178 if (ret) { 1179 ERROR("Message alloc failed (%d)\n", ret); 1180 return ret; 1181 } 1182 1183 req.dev_id = dev_id; 1184 req.clk_id = clk_id; 1185 1186 ret = ti_sci_do_xfer(&xfer); 1187 if (ret) { 1188 ERROR("Transfer send failed (%d)\n", ret); 1189 return ret; 1190 } 1191 1192 *freq = resp.freq_hz; 1193 1194 return 0; 1195 } 1196 1197 /** 1198 * ti_sci_core_reboot() - Command to request system reset 1199 * 1200 * Return: 0 if all goes well, else appropriate error message 1201 */ 1202 int ti_sci_core_reboot(void) 1203 { 1204 struct ti_sci_msg_req_reboot req; 1205 struct ti_sci_msg_hdr resp; 1206 1207 struct ti_sci_xfer xfer; 1208 int ret; 1209 1210 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SYS_RESET, 0, 1211 &req, sizeof(req), 1212 &resp, sizeof(resp), 1213 &xfer); 1214 if (ret) { 1215 ERROR("Message alloc failed (%d)\n", ret); 1216 return ret; 1217 } 1218 req.domain = TI_SCI_DOMAIN_FULL_SOC_RESET; 1219 1220 ret = ti_sci_do_xfer(&xfer); 1221 if (ret) { 1222 ERROR("Transfer send failed (%d)\n", ret); 1223 return ret; 1224 } 1225 1226 return 0; 1227 } 1228 1229 /** 1230 * ti_sci_proc_request() - Request a physical processor control 1231 * 1232 * @proc_id: Processor ID this request is for 1233 * 1234 * Return: 0 if all goes well, else appropriate error message 1235 */ 1236 int ti_sci_proc_request(uint8_t proc_id) 1237 { 1238 struct ti_sci_msg_req_proc_request req; 1239 struct ti_sci_msg_hdr resp; 1240 1241 struct ti_sci_xfer xfer; 1242 int ret; 1243 1244 ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST, 0, 1245 &req, sizeof(req), 1246 &resp, sizeof(resp), 1247 &xfer); 1248 if (ret) { 1249 ERROR("Message alloc failed (%d)\n", ret); 1250 return ret; 1251 } 1252 1253 req.processor_id = proc_id; 1254 1255 ret = ti_sci_do_xfer(&xfer); 1256 if (ret) { 1257 ERROR("Transfer send failed (%d)\n", ret); 1258 return ret; 1259 } 1260 1261 return 0; 1262 } 1263 1264 /** 1265 * ti_sci_proc_release() - Release a physical processor control 1266 * 1267 * @proc_id: Processor ID this request is for 1268 * 1269 * Return: 0 if all goes well, else appropriate error message 1270 */ 1271 int ti_sci_proc_release(uint8_t proc_id) 1272 { 1273 struct ti_sci_msg_req_proc_release req; 1274 struct ti_sci_msg_hdr resp; 1275 1276 struct ti_sci_xfer xfer; 1277 int ret; 1278 1279 ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE, 0, 1280 &req, sizeof(req), 1281 &resp, sizeof(resp), 1282 &xfer); 1283 if (ret) { 1284 ERROR("Message alloc failed (%d)\n", ret); 1285 return ret; 1286 } 1287 1288 req.processor_id = proc_id; 1289 1290 ret = ti_sci_do_xfer(&xfer); 1291 if (ret) { 1292 ERROR("Transfer send failed (%d)\n", ret); 1293 return ret; 1294 } 1295 1296 return 0; 1297 } 1298 1299 /** 1300 * ti_sci_proc_handover() - Handover a physical processor control to a host in 1301 * the processor's access control list. 1302 * 1303 * @proc_id: Processor ID this request is for 1304 * @host_id: Host ID to get the control of the processor 1305 * 1306 * Return: 0 if all goes well, else appropriate error message 1307 */ 1308 int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id) 1309 { 1310 struct ti_sci_msg_req_proc_handover req; 1311 struct ti_sci_msg_hdr resp; 1312 1313 struct ti_sci_xfer xfer; 1314 int ret; 1315 1316 ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER, 0, 1317 &req, sizeof(req), 1318 &resp, sizeof(resp), 1319 &xfer); 1320 if (ret) { 1321 ERROR("Message alloc failed (%d)\n", ret); 1322 return ret; 1323 } 1324 1325 req.processor_id = proc_id; 1326 req.host_id = host_id; 1327 1328 ret = ti_sci_do_xfer(&xfer); 1329 if (ret) { 1330 ERROR("Transfer send failed (%d)\n", ret); 1331 return ret; 1332 } 1333 1334 return 0; 1335 } 1336 1337 /** 1338 * ti_sci_proc_set_boot_cfg() - Set the processor boot configuration flags 1339 * 1340 * @proc_id: Processor ID this request is for 1341 * @config_flags_set: Configuration flags to be set 1342 * @config_flags_clear: Configuration flags to be cleared 1343 * 1344 * Return: 0 if all goes well, else appropriate error message 1345 */ 1346 int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector, 1347 uint32_t config_flags_set, 1348 uint32_t config_flags_clear) 1349 { 1350 struct ti_sci_msg_req_set_proc_boot_config req; 1351 struct ti_sci_msg_hdr resp; 1352 1353 struct ti_sci_xfer xfer; 1354 int ret; 1355 1356 ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CONFIG, 0, 1357 &req, sizeof(req), 1358 &resp, sizeof(resp), 1359 &xfer); 1360 if (ret) { 1361 ERROR("Message alloc failed (%d)\n", ret); 1362 return ret; 1363 } 1364 1365 req.processor_id = proc_id; 1366 req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK; 1367 req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >> 1368 TISCI_ADDR_HIGH_SHIFT; 1369 req.config_flags_set = config_flags_set; 1370 req.config_flags_clear = config_flags_clear; 1371 1372 ret = ti_sci_do_xfer(&xfer); 1373 if (ret) { 1374 ERROR("Transfer send failed (%d)\n", ret); 1375 return ret; 1376 } 1377 1378 return 0; 1379 } 1380 1381 /** 1382 * ti_sci_proc_set_boot_ctrl() - Set the processor boot control flags 1383 * 1384 * @proc_id: Processor ID this request is for 1385 * @control_flags_set: Control flags to be set 1386 * @control_flags_clear: Control flags to be cleared 1387 * 1388 * Return: 0 if all goes well, else appropriate error message 1389 */ 1390 int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set, 1391 uint32_t control_flags_clear) 1392 { 1393 struct ti_sci_msg_req_set_proc_boot_ctrl req; 1394 struct ti_sci_msg_hdr resp; 1395 1396 struct ti_sci_xfer xfer; 1397 int ret; 1398 1399 ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL, 0, 1400 &req, sizeof(req), 1401 &resp, sizeof(resp), 1402 &xfer); 1403 if (ret) { 1404 ERROR("Message alloc failed (%d)\n", ret); 1405 return ret; 1406 } 1407 1408 req.processor_id = proc_id; 1409 req.control_flags_set = control_flags_set; 1410 req.control_flags_clear = control_flags_clear; 1411 1412 ret = ti_sci_do_xfer(&xfer); 1413 if (ret) { 1414 ERROR("Transfer send failed (%d)\n", ret); 1415 return ret; 1416 } 1417 1418 return 0; 1419 } 1420 1421 /** 1422 * ti_sci_proc_set_boot_ctrl_no_wait() - Set the processor boot control flags 1423 * without requesting or waiting for a 1424 * response. 1425 * 1426 * @proc_id: Processor ID this request is for 1427 * @control_flags_set: Control flags to be set 1428 * @control_flags_clear: Control flags to be cleared 1429 * 1430 * Return: 0 if all goes well, else appropriate error message 1431 */ 1432 int ti_sci_proc_set_boot_ctrl_no_wait(uint8_t proc_id, 1433 uint32_t control_flags_set, 1434 uint32_t control_flags_clear) 1435 { 1436 struct ti_sci_msg_req_set_proc_boot_ctrl req; 1437 struct ti_sci_xfer xfer; 1438 int ret; 1439 1440 ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL, 0, 1441 &req, sizeof(req), 1442 NULL, 0, 1443 &xfer); 1444 if (ret != 0U) { 1445 ERROR("Message alloc failed (%d)\n", ret); 1446 return ret; 1447 } 1448 1449 req.processor_id = proc_id; 1450 req.control_flags_set = control_flags_set; 1451 req.control_flags_clear = control_flags_clear; 1452 1453 ret = ti_sci_do_xfer(&xfer); 1454 if (ret != 0U) { 1455 ERROR("Transfer send failed (%d)\n", ret); 1456 return ret; 1457 } 1458 1459 return 0; 1460 } 1461 1462 /** 1463 * ti_sci_proc_auth_boot_image() - Authenticate and load image and then set the 1464 * processor configuration flags 1465 * 1466 * @proc_id: Processor ID this request is for 1467 * @cert_addr: Memory address at which payload image certificate is located 1468 * 1469 * Return: 0 if all goes well, else appropriate error message 1470 */ 1471 int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr) 1472 { 1473 struct ti_sci_msg_req_proc_auth_boot_image req; 1474 struct ti_sci_msg_hdr resp; 1475 1476 struct ti_sci_xfer xfer; 1477 int ret; 1478 1479 ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMAGE, 0, 1480 &req, sizeof(req), 1481 &resp, sizeof(resp), 1482 &xfer); 1483 if (ret) { 1484 ERROR("Message alloc failed (%d)\n", ret); 1485 return ret; 1486 } 1487 1488 req.processor_id = proc_id; 1489 req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK; 1490 req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >> 1491 TISCI_ADDR_HIGH_SHIFT; 1492 1493 ret = ti_sci_do_xfer(&xfer); 1494 if (ret) { 1495 ERROR("Transfer send failed (%d)\n", ret); 1496 return ret; 1497 } 1498 1499 return 0; 1500 } 1501 1502 /** 1503 * ti_sci_proc_get_boot_status() - Get the processor boot status 1504 * 1505 * @proc_id: Processor ID this request is for 1506 * 1507 * Return: 0 if all goes well, else appropriate error message 1508 */ 1509 int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv, 1510 uint32_t *cfg_flags, 1511 uint32_t *ctrl_flags, 1512 uint32_t *sts_flags) 1513 { 1514 struct ti_sci_msg_req_get_proc_boot_status req; 1515 struct ti_sci_msg_resp_get_proc_boot_status resp; 1516 1517 struct ti_sci_xfer xfer; 1518 int ret; 1519 1520 ret = ti_sci_setup_one_xfer(TISCI_MSG_GET_PROC_BOOT_STATUS, 0, 1521 &req, sizeof(req), 1522 &resp, sizeof(resp), 1523 &xfer); 1524 if (ret) { 1525 ERROR("Message alloc failed (%d)\n", ret); 1526 return ret; 1527 } 1528 1529 req.processor_id = proc_id; 1530 1531 ret = ti_sci_do_xfer(&xfer); 1532 if (ret) { 1533 ERROR("Transfer send failed (%d)\n", ret); 1534 return ret; 1535 } 1536 1537 *bv = (resp.bootvector_low & TISCI_ADDR_LOW_MASK) | 1538 (((uint64_t)resp.bootvector_high << TISCI_ADDR_HIGH_SHIFT) & 1539 TISCI_ADDR_HIGH_MASK); 1540 *cfg_flags = resp.config_flags; 1541 *ctrl_flags = resp.control_flags; 1542 *sts_flags = resp.status_flags; 1543 1544 return 0; 1545 } 1546 1547 /** 1548 * ti_sci_proc_wait_boot_status() - Wait for a processor boot status 1549 * 1550 * @proc_id: Processor ID this request is for 1551 * @num_wait_iterations Total number of iterations we will check before 1552 * we will timeout and give up 1553 * @num_match_iterations How many iterations should we have continued 1554 * status to account for status bits glitching. 1555 * This is to make sure that match occurs for 1556 * consecutive checks. This implies that the 1557 * worst case should consider that the stable 1558 * time should at the worst be num_wait_iterations 1559 * num_match_iterations to prevent timeout. 1560 * @delay_per_iteration_us Specifies how long to wait (in micro seconds) 1561 * between each status checks. This is the minimum 1562 * duration, and overhead of register reads and 1563 * checks are on top of this and can vary based on 1564 * varied conditions. 1565 * @delay_before_iterations_us Specifies how long to wait (in micro seconds) 1566 * before the very first check in the first 1567 * iteration of status check loop. This is the 1568 * minimum duration, and overhead of register 1569 * reads and checks are. 1570 * @status_flags_1_set_all_wait If non-zero, Specifies that all bits of the 1571 * status matching this field requested MUST be 1. 1572 * @status_flags_1_set_any_wait If non-zero, Specifies that at least one of the 1573 * bits matching this field requested MUST be 1. 1574 * @status_flags_1_clr_all_wait If non-zero, Specifies that all bits of the 1575 * status matching this field requested MUST be 0. 1576 * @status_flags_1_clr_any_wait If non-zero, Specifies that at least one of the 1577 * bits matching this field requested MUST be 0. 1578 * 1579 * Return: 0 if all goes well, else appropriate error message 1580 */ 1581 int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations, 1582 uint8_t num_match_iterations, 1583 uint8_t delay_per_iteration_us, 1584 uint8_t delay_before_iterations_us, 1585 uint32_t status_flags_1_set_all_wait, 1586 uint32_t status_flags_1_set_any_wait, 1587 uint32_t status_flags_1_clr_all_wait, 1588 uint32_t status_flags_1_clr_any_wait) 1589 { 1590 struct ti_sci_msg_req_wait_proc_boot_status req; 1591 struct ti_sci_msg_hdr resp; 1592 1593 struct ti_sci_xfer xfer; 1594 int ret; 1595 1596 ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS, 0, 1597 &req, sizeof(req), 1598 &resp, sizeof(resp), 1599 &xfer); 1600 if (ret) { 1601 ERROR("Message alloc failed (%d)\n", ret); 1602 return ret; 1603 } 1604 1605 req.processor_id = proc_id; 1606 req.num_wait_iterations = num_wait_iterations; 1607 req.num_match_iterations = num_match_iterations; 1608 req.delay_per_iteration_us = delay_per_iteration_us; 1609 req.delay_before_iterations_us = delay_before_iterations_us; 1610 req.status_flags_1_set_all_wait = status_flags_1_set_all_wait; 1611 req.status_flags_1_set_any_wait = status_flags_1_set_any_wait; 1612 req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait; 1613 req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait; 1614 1615 ret = ti_sci_do_xfer(&xfer); 1616 if (ret) { 1617 ERROR("Transfer send failed (%d)\n", ret); 1618 return ret; 1619 } 1620 1621 return 0; 1622 } 1623 1624 /** 1625 * ti_sci_proc_wait_boot_status_no_wait() - Wait for a processor boot status 1626 * without requesting or waiting for 1627 * a response. 1628 * 1629 * @proc_id: Processor ID this request is for 1630 * @num_wait_iterations Total number of iterations we will check before 1631 * we will timeout and give up 1632 * @num_match_iterations How many iterations should we have continued 1633 * status to account for status bits glitching. 1634 * This is to make sure that match occurs for 1635 * consecutive checks. This implies that the 1636 * worst case should consider that the stable 1637 * time should at the worst be num_wait_iterations 1638 * num_match_iterations to prevent timeout. 1639 * @delay_per_iteration_us Specifies how long to wait (in micro seconds) 1640 * between each status checks. This is the minimum 1641 * duration, and overhead of register reads and 1642 * checks are on top of this and can vary based on 1643 * varied conditions. 1644 * @delay_before_iterations_us Specifies how long to wait (in micro seconds) 1645 * before the very first check in the first 1646 * iteration of status check loop. This is the 1647 * minimum duration, and overhead of register 1648 * reads and checks are. 1649 * @status_flags_1_set_all_wait If non-zero, Specifies that all bits of the 1650 * status matching this field requested MUST be 1. 1651 * @status_flags_1_set_any_wait If non-zero, Specifies that at least one of the 1652 * bits matching this field requested MUST be 1. 1653 * @status_flags_1_clr_all_wait If non-zero, Specifies that all bits of the 1654 * status matching this field requested MUST be 0. 1655 * @status_flags_1_clr_any_wait If non-zero, Specifies that at least one of the 1656 * bits matching this field requested MUST be 0. 1657 * 1658 * Return: 0 if all goes well, else appropriate error message 1659 */ 1660 int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id, 1661 uint8_t num_wait_iterations, 1662 uint8_t num_match_iterations, 1663 uint8_t delay_per_iteration_us, 1664 uint8_t delay_before_iterations_us, 1665 uint32_t status_flags_1_set_all_wait, 1666 uint32_t status_flags_1_set_any_wait, 1667 uint32_t status_flags_1_clr_all_wait, 1668 uint32_t status_flags_1_clr_any_wait) 1669 { 1670 struct ti_sci_msg_req_wait_proc_boot_status req; 1671 struct ti_sci_xfer xfer; 1672 int ret; 1673 1674 ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS, 0, 1675 &req, sizeof(req), 1676 NULL, 0, 1677 &xfer); 1678 if (ret != 0U) { 1679 ERROR("Message alloc failed (%d)\n", ret); 1680 return ret; 1681 } 1682 1683 req.processor_id = proc_id; 1684 req.num_wait_iterations = num_wait_iterations; 1685 req.num_match_iterations = num_match_iterations; 1686 req.delay_per_iteration_us = delay_per_iteration_us; 1687 req.delay_before_iterations_us = delay_before_iterations_us; 1688 req.status_flags_1_set_all_wait = status_flags_1_set_all_wait; 1689 req.status_flags_1_set_any_wait = status_flags_1_set_any_wait; 1690 req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait; 1691 req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait; 1692 1693 ret = ti_sci_do_xfer(&xfer); 1694 if (ret != 0U) { 1695 ERROR("Transfer send failed (%d)\n", ret); 1696 return ret; 1697 } 1698 1699 return 0; 1700 } 1701 1702 /** 1703 * ti_sci_enter_sleep - Command to initiate system transition into suspend. 1704 * 1705 * @proc_id: Processor ID. 1706 * @mode: Low power mode to enter. 1707 * @core_resume_addr: Address that core should be 1708 * resumed from after low power transition. 1709 * 1710 * Return: 0 if all goes well, else appropriate error message 1711 */ 1712 int ti_sci_enter_sleep(uint8_t proc_id, 1713 uint8_t mode, 1714 uint64_t core_resume_addr) 1715 { 1716 struct ti_sci_msg_req_enter_sleep req; 1717 struct ti_sci_xfer xfer; 1718 int ret; 1719 1720 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_ENTER_SLEEP, 0, 1721 &req, sizeof(req), 1722 NULL, 0, 1723 &xfer); 1724 if (ret != 0U) { 1725 ERROR("Message alloc failed (%d)\n", ret); 1726 return ret; 1727 } 1728 1729 req.processor_id = proc_id; 1730 req.mode = mode; 1731 req.core_resume_lo = core_resume_addr & TISCI_ADDR_LOW_MASK; 1732 req.core_resume_hi = (core_resume_addr & TISCI_ADDR_HIGH_MASK) >> 1733 TISCI_ADDR_HIGH_SHIFT; 1734 1735 ret = ti_sci_do_xfer(&xfer); 1736 if (ret != 0U) { 1737 ERROR("Transfer send failed (%d)\n", ret); 1738 return ret; 1739 } 1740 1741 return 0; 1742 } 1743 1744 /** 1745 * ti_sci_lpm_get_next_sys_mode() - Get next LPM system mode 1746 * 1747 * @next_mode: pointer to a variable that will store the next mode 1748 * 1749 * Return: 0 if all goes well, else appropriate error message 1750 */ 1751 int ti_sci_lpm_get_next_sys_mode(uint8_t *next_mode) 1752 { 1753 struct ti_sci_msg_req_lpm_get_next_sys_mode req; 1754 struct ti_sci_msg_resp_lpm_get_next_sys_mode resp; 1755 struct ti_sci_xfer xfer; 1756 int ret; 1757 1758 if (next_mode == NULL) { 1759 return -EINVAL; 1760 } 1761 1762 ret = ti_sci_setup_one_xfer(TI_SCI_MSG_LPM_GET_NEXT_SYS_MODE, 0, 1763 &req, sizeof(req), 1764 &resp, sizeof(resp), 1765 &xfer); 1766 if (ret != 0) { 1767 ERROR("Message alloc failed (%d)\n", ret); 1768 return ret; 1769 } 1770 1771 ret = ti_sci_do_xfer(&xfer); 1772 if (ret != 0) { 1773 ERROR("Transfer send failed (%d)\n", ret); 1774 return ret; 1775 } 1776 1777 *next_mode = resp.mode; 1778 1779 return 0; 1780 } 1781