1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Texas Instruments System Control Interface Protocol Driver 4 * Based on drivers/firmware/ti_sci.c from Linux. 5 * 6 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 7 * Lokesh Vutla <lokeshvutla@ti.com> 8 */ 9 10 #include <common.h> 11 #include <dm.h> 12 #include <errno.h> 13 #include <mailbox.h> 14 #include <dm/device.h> 15 #include <linux/err.h> 16 #include <linux/soc/ti/k3-sec-proxy.h> 17 #include <linux/soc/ti/ti_sci_protocol.h> 18 19 #include "ti_sci.h" 20 21 /* List of all TI SCI devices active in system */ 22 static LIST_HEAD(ti_sci_list); 23 24 /** 25 * struct ti_sci_xfer - Structure representing a message flow 26 * @tx_message: Transmit message 27 * @rx_len: Receive message length 28 */ 29 struct ti_sci_xfer { 30 struct k3_sec_proxy_msg tx_message; 31 u8 rx_len; 32 }; 33 34 /** 35 * struct ti_sci_desc - Description of SoC integration 36 * @host_id: Host identifier representing the compute entity 37 * @max_rx_timeout_us: Timeout for communication with SoC (in Microseconds) 38 * @max_msg_size: Maximum size of data per message that can be handled. 39 */ 40 struct ti_sci_desc { 41 u8 host_id; 42 int max_rx_timeout_us; 43 int max_msg_size; 44 }; 45 46 /** 47 * struct ti_sci_info - Structure representing a TI SCI instance 48 * @dev: Device pointer 49 * @desc: SoC description for this instance 50 * @handle: Instance of TI SCI handle to send to clients. 51 * @chan_tx: Transmit mailbox channel 52 * @chan_rx: Receive mailbox channel 53 * @xfer: xfer info 54 * @list: list head 55 * @is_secure: Determines if the communication is through secure threads. 56 * @host_id: Host identifier representing the compute entity 57 * @seq: Seq id used for verification for tx and rx message. 58 */ 59 struct ti_sci_info { 60 struct udevice *dev; 61 const struct ti_sci_desc *desc; 62 struct ti_sci_handle handle; 63 struct mbox_chan chan_tx; 64 struct mbox_chan chan_rx; 65 struct mbox_chan chan_notify; 66 struct ti_sci_xfer xfer; 67 struct list_head list; 68 bool is_secure; 69 u8 host_id; 70 u8 seq; 71 }; 72 73 #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle) 74 75 /** 76 * ti_sci_setup_one_xfer() - Setup one message type 77 * @info: Pointer to SCI entity information 78 * @msg_type: Message type 79 * @msg_flags: Flag to set for the message 80 * @buf: Buffer to be send to mailbox channel 81 * @tx_message_size: transmit message size 82 * @rx_message_size: receive message size 83 * 84 * Helper function which is used by various command functions that are 85 * exposed to clients of this driver for allocating a message traffic event. 86 * 87 * Return: Corresponding ti_sci_xfer pointer if all went fine, 88 * else appropriate error pointer. 89 */ 90 static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, 91 u16 msg_type, u32 msg_flags, 92 u32 *buf, 93 size_t tx_message_size, 94 size_t rx_message_size) 95 { 96 struct ti_sci_xfer *xfer = &info->xfer; 97 struct ti_sci_msg_hdr *hdr; 98 99 /* Ensure we have sane transfer sizes */ 100 if (rx_message_size > info->desc->max_msg_size || 101 tx_message_size > info->desc->max_msg_size || 102 rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr)) 103 return ERR_PTR(-ERANGE); 104 105 info->seq = ~info->seq; 106 xfer->tx_message.buf = buf; 107 xfer->tx_message.len = tx_message_size; 108 xfer->rx_len = (u8)rx_message_size; 109 110 hdr = (struct ti_sci_msg_hdr *)buf; 111 hdr->seq = info->seq; 112 hdr->type = msg_type; 113 hdr->host = info->host_id; 114 hdr->flags = msg_flags; 115 116 return xfer; 117 } 118 119 /** 120 * ti_sci_get_response() - Receive response from mailbox channel 121 * @info: Pointer to SCI entity information 122 * @xfer: Transfer to initiate and wait for response 123 * @chan: Channel to receive the response 124 * 125 * Return: -ETIMEDOUT in case of no response, if transmit error, 126 * return corresponding error, else if all goes well, 127 * return 0. 128 */ 129 static inline int ti_sci_get_response(struct ti_sci_info *info, 130 struct ti_sci_xfer *xfer, 131 struct mbox_chan *chan) 132 { 133 struct k3_sec_proxy_msg *msg = &xfer->tx_message; 134 struct ti_sci_secure_msg_hdr *secure_hdr; 135 struct ti_sci_msg_hdr *hdr; 136 int ret; 137 138 /* Receive the response */ 139 ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_us); 140 if (ret) { 141 dev_err(info->dev, "%s: Message receive failed. ret = %d\n", 142 __func__, ret); 143 return ret; 144 } 145 146 /* ToDo: Verify checksum */ 147 if (info->is_secure) { 148 secure_hdr = (struct ti_sci_secure_msg_hdr *)msg->buf; 149 msg->buf = (u32 *)((void *)msg->buf + sizeof(*secure_hdr)); 150 } 151 152 /* msg is updated by mailbox driver */ 153 hdr = (struct ti_sci_msg_hdr *)msg->buf; 154 155 /* Sanity check for message response */ 156 if (hdr->seq != info->seq) { 157 dev_dbg(info->dev, "%s: Message for %d is not expected\n", 158 __func__, hdr->seq); 159 return ret; 160 } 161 162 if (msg->len > info->desc->max_msg_size) { 163 dev_err(info->dev, "%s: Unable to handle %zu xfer (max %d)\n", 164 __func__, msg->len, info->desc->max_msg_size); 165 return -EINVAL; 166 } 167 168 if (msg->len < xfer->rx_len) { 169 dev_err(info->dev, "%s: Recv xfer %zu < expected %d length\n", 170 __func__, msg->len, xfer->rx_len); 171 } 172 173 return ret; 174 } 175 176 /** 177 * ti_sci_do_xfer() - Do one transfer 178 * @info: Pointer to SCI entity information 179 * @xfer: Transfer to initiate and wait for response 180 * 181 * Return: 0 if all went fine, else return appropriate error. 182 */ 183 static inline int ti_sci_do_xfer(struct ti_sci_info *info, 184 struct ti_sci_xfer *xfer) 185 { 186 struct k3_sec_proxy_msg *msg = &xfer->tx_message; 187 u8 secure_buf[info->desc->max_msg_size]; 188 struct ti_sci_secure_msg_hdr secure_hdr; 189 int ret; 190 191 if (info->is_secure) { 192 /* ToDo: get checksum of the entire message */ 193 secure_hdr.checksum = 0; 194 secure_hdr.reserved = 0; 195 memcpy(&secure_buf[sizeof(secure_hdr)], xfer->tx_message.buf, 196 xfer->tx_message.len); 197 198 xfer->tx_message.buf = (u32 *)secure_buf; 199 xfer->tx_message.len += sizeof(secure_hdr); 200 xfer->rx_len += sizeof(secure_hdr); 201 } 202 203 /* Send the message */ 204 ret = mbox_send(&info->chan_tx, msg); 205 if (ret) { 206 dev_err(info->dev, "%s: Message sending failed. ret = %d\n", 207 __func__, ret); 208 return ret; 209 } 210 211 return ti_sci_get_response(info, xfer, &info->chan_rx); 212 } 213 214 /** 215 * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity 216 * @handle: pointer to TI SCI handle 217 * 218 * Updates the SCI information in the internal data structure. 219 * 220 * Return: 0 if all went fine, else return appropriate error. 221 */ 222 static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) 223 { 224 struct ti_sci_msg_resp_version *rev_info; 225 struct ti_sci_version_info *ver; 226 struct ti_sci_msg_hdr hdr; 227 struct ti_sci_info *info; 228 struct ti_sci_xfer *xfer; 229 int ret; 230 231 if (IS_ERR(handle)) 232 return PTR_ERR(handle); 233 if (!handle) 234 return -EINVAL; 235 236 info = handle_to_ti_sci_info(handle); 237 238 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION, 0x0, 239 (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr), 240 sizeof(*rev_info)); 241 if (IS_ERR(xfer)) { 242 ret = PTR_ERR(xfer); 243 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 244 return ret; 245 } 246 247 ret = ti_sci_do_xfer(info, xfer); 248 if (ret) { 249 dev_err(info->dev, "Mbox communication fail %d\n", ret); 250 return ret; 251 } 252 253 rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf; 254 255 ver = &handle->version; 256 ver->abi_major = rev_info->abi_major; 257 ver->abi_minor = rev_info->abi_minor; 258 ver->firmware_revision = rev_info->firmware_revision; 259 strncpy(ver->firmware_description, rev_info->firmware_description, 260 sizeof(ver->firmware_description)); 261 262 return 0; 263 } 264 265 /** 266 * ti_sci_is_response_ack() - Generic ACK/NACK message checkup 267 * @r: pointer to response buffer 268 * 269 * Return: true if the response was an ACK, else returns false. 270 */ 271 static inline bool ti_sci_is_response_ack(void *r) 272 { 273 struct ti_sci_msg_hdr *hdr = r; 274 275 return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; 276 } 277 278 /** 279 * cmd_set_board_config_using_msg() - Common command to send board configuration 280 * message 281 * @handle: pointer to TI SCI handle 282 * @msg_type: One of the TISCI message types to set board configuration 283 * @addr: Address where the board config structure is located 284 * @size: Size of the board config structure 285 * 286 * Return: 0 if all went well, else returns appropriate error value. 287 */ 288 static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, 289 u16 msg_type, u64 addr, u32 size) 290 { 291 struct ti_sci_msg_board_config req; 292 struct ti_sci_msg_hdr *resp; 293 struct ti_sci_info *info; 294 struct ti_sci_xfer *xfer; 295 int ret = 0; 296 297 if (IS_ERR(handle)) 298 return PTR_ERR(handle); 299 if (!handle) 300 return -EINVAL; 301 302 info = handle_to_ti_sci_info(handle); 303 304 xfer = ti_sci_setup_one_xfer(info, msg_type, 305 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 306 (u32 *)&req, sizeof(req), sizeof(*resp)); 307 if (IS_ERR(xfer)) { 308 ret = PTR_ERR(xfer); 309 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 310 return ret; 311 } 312 req.boardcfgp_high = (addr >> 32) & 0xffffffff; 313 req.boardcfgp_low = addr & 0xffffffff; 314 req.boardcfg_size = size; 315 316 ret = ti_sci_do_xfer(info, xfer); 317 if (ret) { 318 dev_err(info->dev, "Mbox send fail %d\n", ret); 319 return ret; 320 } 321 322 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 323 324 if (!ti_sci_is_response_ack(resp)) 325 return -ENODEV; 326 327 return ret; 328 } 329 330 /** 331 * ti_sci_cmd_set_board_config() - Command to send board configuration message 332 * @handle: pointer to TI SCI handle 333 * @addr: Address where the board config structure is located 334 * @size: Size of the board config structure 335 * 336 * Return: 0 if all went well, else returns appropriate error value. 337 */ 338 static int ti_sci_cmd_set_board_config(const struct ti_sci_handle *handle, 339 u64 addr, u32 size) 340 { 341 return cmd_set_board_config_using_msg(handle, 342 TI_SCI_MSG_BOARD_CONFIG, 343 addr, size); 344 } 345 346 /** 347 * ti_sci_cmd_set_board_config_rm() - Command to send board resource 348 * management configuration 349 * @handle: pointer to TI SCI handle 350 * @addr: Address where the board RM config structure is located 351 * @size: Size of the RM config structure 352 * 353 * Return: 0 if all went well, else returns appropriate error value. 354 */ 355 static 356 int ti_sci_cmd_set_board_config_rm(const struct ti_sci_handle *handle, 357 u64 addr, u32 size) 358 { 359 return cmd_set_board_config_using_msg(handle, 360 TI_SCI_MSG_BOARD_CONFIG_RM, 361 addr, size); 362 } 363 364 /** 365 * ti_sci_cmd_set_board_config_security() - Command to send board security 366 * configuration message 367 * @handle: pointer to TI SCI handle 368 * @addr: Address where the board security config structure is located 369 * @size: Size of the security config structure 370 * 371 * Return: 0 if all went well, else returns appropriate error value. 372 */ 373 static 374 int ti_sci_cmd_set_board_config_security(const struct ti_sci_handle *handle, 375 u64 addr, u32 size) 376 { 377 return cmd_set_board_config_using_msg(handle, 378 TI_SCI_MSG_BOARD_CONFIG_SECURITY, 379 addr, size); 380 } 381 382 /** 383 * ti_sci_cmd_set_board_config_pm() - Command to send board power and clock 384 * configuration message 385 * @handle: pointer to TI SCI handle 386 * @addr: Address where the board PM config structure is located 387 * @size: Size of the PM config structure 388 * 389 * Return: 0 if all went well, else returns appropriate error value. 390 */ 391 static int ti_sci_cmd_set_board_config_pm(const struct ti_sci_handle *handle, 392 u64 addr, u32 size) 393 { 394 return cmd_set_board_config_using_msg(handle, 395 TI_SCI_MSG_BOARD_CONFIG_PM, 396 addr, size); 397 } 398 399 /** 400 * ti_sci_set_device_state() - Set device state helper 401 * @handle: pointer to TI SCI handle 402 * @id: Device identifier 403 * @flags: flags to setup for the device 404 * @state: State to move the device to 405 * 406 * Return: 0 if all went well, else returns appropriate error value. 407 */ 408 static int ti_sci_set_device_state(const struct ti_sci_handle *handle, 409 u32 id, u32 flags, u8 state) 410 { 411 struct ti_sci_msg_req_set_device_state req; 412 struct ti_sci_msg_hdr *resp; 413 struct ti_sci_info *info; 414 struct ti_sci_xfer *xfer; 415 int ret = 0; 416 417 if (IS_ERR(handle)) 418 return PTR_ERR(handle); 419 if (!handle) 420 return -EINVAL; 421 422 info = handle_to_ti_sci_info(handle); 423 424 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE, 425 flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 426 (u32 *)&req, sizeof(req), sizeof(*resp)); 427 if (IS_ERR(xfer)) { 428 ret = PTR_ERR(xfer); 429 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 430 return ret; 431 } 432 req.id = id; 433 req.state = state; 434 435 ret = ti_sci_do_xfer(info, xfer); 436 if (ret) { 437 dev_err(info->dev, "Mbox send fail %d\n", ret); 438 return ret; 439 } 440 441 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 442 443 if (!ti_sci_is_response_ack(resp)) 444 return -ENODEV; 445 446 return ret; 447 } 448 449 /** 450 * ti_sci_get_device_state() - Get device state helper 451 * @handle: Handle to the device 452 * @id: Device Identifier 453 * @clcnt: Pointer to Context Loss Count 454 * @resets: pointer to resets 455 * @p_state: pointer to p_state 456 * @c_state: pointer to c_state 457 * 458 * Return: 0 if all went fine, else return appropriate error. 459 */ 460 static int ti_sci_get_device_state(const struct ti_sci_handle *handle, 461 u32 id, u32 *clcnt, u32 *resets, 462 u8 *p_state, u8 *c_state) 463 { 464 struct ti_sci_msg_resp_get_device_state *resp; 465 struct ti_sci_msg_req_get_device_state req; 466 struct ti_sci_info *info; 467 struct ti_sci_xfer *xfer; 468 int ret = 0; 469 470 if (IS_ERR(handle)) 471 return PTR_ERR(handle); 472 if (!handle) 473 return -EINVAL; 474 475 if (!clcnt && !resets && !p_state && !c_state) 476 return -EINVAL; 477 478 info = handle_to_ti_sci_info(handle); 479 480 /* Response is expected, so need of any flags */ 481 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE, 0, 482 (u32 *)&req, sizeof(req), sizeof(*resp)); 483 if (IS_ERR(xfer)) { 484 ret = PTR_ERR(xfer); 485 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 486 return ret; 487 } 488 req.id = id; 489 490 ret = ti_sci_do_xfer(info, xfer); 491 if (ret) { 492 dev_err(dev, "Mbox send fail %d\n", ret); 493 return ret; 494 } 495 496 resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf; 497 if (!ti_sci_is_response_ack(resp)) 498 return -ENODEV; 499 500 if (clcnt) 501 *clcnt = resp->context_loss_count; 502 if (resets) 503 *resets = resp->resets; 504 if (p_state) 505 *p_state = resp->programmed_state; 506 if (c_state) 507 *c_state = resp->current_state; 508 509 return ret; 510 } 511 512 /** 513 * ti_sci_cmd_get_device() - command to request for device managed by TISCI 514 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 515 * @id: Device Identifier 516 * 517 * Request for the device - NOTE: the client MUST maintain integrity of 518 * usage count by balancing get_device with put_device. No refcounting is 519 * managed by driver for that purpose. 520 * 521 * NOTE: The request is for exclusive access for the processor. 522 * 523 * Return: 0 if all went fine, else return appropriate error. 524 */ 525 static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id) 526 { 527 return ti_sci_set_device_state(handle, id, 528 MSG_FLAG_DEVICE_EXCLUSIVE, 529 MSG_DEVICE_SW_STATE_ON); 530 } 531 532 /** 533 * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI 534 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 535 * @id: Device Identifier 536 * 537 * Request for the device - NOTE: the client MUST maintain integrity of 538 * usage count by balancing get_device with put_device. No refcounting is 539 * managed by driver for that purpose. 540 * 541 * Return: 0 if all went fine, else return appropriate error. 542 */ 543 static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id) 544 { 545 return ti_sci_set_device_state(handle, id, 546 MSG_FLAG_DEVICE_EXCLUSIVE, 547 MSG_DEVICE_SW_STATE_RETENTION); 548 } 549 550 /** 551 * ti_sci_cmd_put_device() - command to release a device managed by TISCI 552 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 553 * @id: Device Identifier 554 * 555 * Request for the device - NOTE: the client MUST maintain integrity of 556 * usage count by balancing get_device with put_device. No refcounting is 557 * managed by driver for that purpose. 558 * 559 * Return: 0 if all went fine, else return appropriate error. 560 */ 561 static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id) 562 { 563 return ti_sci_set_device_state(handle, id, 564 0, MSG_DEVICE_SW_STATE_AUTO_OFF); 565 } 566 567 /** 568 * ti_sci_cmd_dev_is_valid() - Is the device valid 569 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 570 * @id: Device Identifier 571 * 572 * Return: 0 if all went fine and the device ID is valid, else return 573 * appropriate error. 574 */ 575 static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id) 576 { 577 u8 unused; 578 579 /* check the device state which will also tell us if the ID is valid */ 580 return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused); 581 } 582 583 /** 584 * ti_sci_cmd_dev_get_clcnt() - Get context loss counter 585 * @handle: Pointer to TISCI handle 586 * @id: Device Identifier 587 * @count: Pointer to Context Loss counter to populate 588 * 589 * Return: 0 if all went fine, else return appropriate error. 590 */ 591 static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id, 592 u32 *count) 593 { 594 return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL); 595 } 596 597 /** 598 * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle 599 * @handle: Pointer to TISCI handle 600 * @id: Device Identifier 601 * @r_state: true if requested to be idle 602 * 603 * Return: 0 if all went fine, else return appropriate error. 604 */ 605 static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id, 606 bool *r_state) 607 { 608 int ret; 609 u8 state; 610 611 if (!r_state) 612 return -EINVAL; 613 614 ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL); 615 if (ret) 616 return ret; 617 618 *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION); 619 620 return 0; 621 } 622 623 /** 624 * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped 625 * @handle: Pointer to TISCI handle 626 * @id: Device Identifier 627 * @r_state: true if requested to be stopped 628 * @curr_state: true if currently stopped. 629 * 630 * Return: 0 if all went fine, else return appropriate error. 631 */ 632 static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id, 633 bool *r_state, bool *curr_state) 634 { 635 int ret; 636 u8 p_state, c_state; 637 638 if (!r_state && !curr_state) 639 return -EINVAL; 640 641 ret = 642 ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state); 643 if (ret) 644 return ret; 645 646 if (r_state) 647 *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF); 648 if (curr_state) 649 *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF); 650 651 return 0; 652 } 653 654 /** 655 * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON 656 * @handle: Pointer to TISCI handle 657 * @id: Device Identifier 658 * @r_state: true if requested to be ON 659 * @curr_state: true if currently ON and active 660 * 661 * Return: 0 if all went fine, else return appropriate error. 662 */ 663 static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id, 664 bool *r_state, bool *curr_state) 665 { 666 int ret; 667 u8 p_state, c_state; 668 669 if (!r_state && !curr_state) 670 return -EINVAL; 671 672 ret = 673 ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state); 674 if (ret) 675 return ret; 676 677 if (r_state) 678 *r_state = (p_state == MSG_DEVICE_SW_STATE_ON); 679 if (curr_state) 680 *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON); 681 682 return 0; 683 } 684 685 /** 686 * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning 687 * @handle: Pointer to TISCI handle 688 * @id: Device Identifier 689 * @curr_state: true if currently transitioning. 690 * 691 * Return: 0 if all went fine, else return appropriate error. 692 */ 693 static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id, 694 bool *curr_state) 695 { 696 int ret; 697 u8 state; 698 699 if (!curr_state) 700 return -EINVAL; 701 702 ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state); 703 if (ret) 704 return ret; 705 706 *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS); 707 708 return 0; 709 } 710 711 /** 712 * ti_sci_cmd_set_device_resets() - command to set resets for device managed 713 * by TISCI 714 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 715 * @id: Device Identifier 716 * @reset_state: Device specific reset bit field 717 * 718 * Return: 0 if all went fine, else return appropriate error. 719 */ 720 static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, 721 u32 id, u32 reset_state) 722 { 723 struct ti_sci_msg_req_set_device_resets req; 724 struct ti_sci_msg_hdr *resp; 725 struct ti_sci_info *info; 726 struct ti_sci_xfer *xfer; 727 int ret = 0; 728 729 if (IS_ERR(handle)) 730 return PTR_ERR(handle); 731 if (!handle) 732 return -EINVAL; 733 734 info = handle_to_ti_sci_info(handle); 735 736 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS, 737 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 738 (u32 *)&req, sizeof(req), sizeof(*resp)); 739 if (IS_ERR(xfer)) { 740 ret = PTR_ERR(xfer); 741 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 742 return ret; 743 } 744 req.id = id; 745 req.resets = reset_state; 746 747 ret = ti_sci_do_xfer(info, xfer); 748 if (ret) { 749 dev_err(info->dev, "Mbox send fail %d\n", ret); 750 return ret; 751 } 752 753 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 754 755 if (!ti_sci_is_response_ack(resp)) 756 return -ENODEV; 757 758 return ret; 759 } 760 761 /** 762 * ti_sci_cmd_get_device_resets() - Get reset state for device managed 763 * by TISCI 764 * @handle: Pointer to TISCI handle 765 * @id: Device Identifier 766 * @reset_state: Pointer to reset state to populate 767 * 768 * Return: 0 if all went fine, else return appropriate error. 769 */ 770 static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle, 771 u32 id, u32 *reset_state) 772 { 773 return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL, 774 NULL); 775 } 776 777 /** 778 * ti_sci_set_clock_state() - Set clock state helper 779 * @handle: pointer to TI SCI handle 780 * @dev_id: Device identifier this request is for 781 * @clk_id: Clock identifier for the device for this request. 782 * Each device has it's own set of clock inputs. This indexes 783 * which clock input to modify. 784 * @flags: Header flags as needed 785 * @state: State to request for the clock. 786 * 787 * Return: 0 if all went well, else returns appropriate error value. 788 */ 789 static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, 790 u32 dev_id, u8 clk_id, 791 u32 flags, u8 state) 792 { 793 struct ti_sci_msg_req_set_clock_state req; 794 struct ti_sci_msg_hdr *resp; 795 struct ti_sci_info *info; 796 struct ti_sci_xfer *xfer; 797 int ret = 0; 798 799 if (IS_ERR(handle)) 800 return PTR_ERR(handle); 801 if (!handle) 802 return -EINVAL; 803 804 info = handle_to_ti_sci_info(handle); 805 806 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE, 807 flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 808 (u32 *)&req, sizeof(req), sizeof(*resp)); 809 if (IS_ERR(xfer)) { 810 ret = PTR_ERR(xfer); 811 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 812 return ret; 813 } 814 req.dev_id = dev_id; 815 req.clk_id = clk_id; 816 req.request_state = state; 817 818 ret = ti_sci_do_xfer(info, xfer); 819 if (ret) { 820 dev_err(info->dev, "Mbox send fail %d\n", ret); 821 return ret; 822 } 823 824 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 825 826 if (!ti_sci_is_response_ack(resp)) 827 return -ENODEV; 828 829 return ret; 830 } 831 832 /** 833 * ti_sci_cmd_get_clock_state() - Get clock state helper 834 * @handle: pointer to TI SCI handle 835 * @dev_id: Device identifier this request is for 836 * @clk_id: Clock identifier for the device for this request. 837 * Each device has it's own set of clock inputs. This indexes 838 * which clock input to modify. 839 * @programmed_state: State requested for clock to move to 840 * @current_state: State that the clock is currently in 841 * 842 * Return: 0 if all went well, else returns appropriate error value. 843 */ 844 static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, 845 u32 dev_id, u8 clk_id, 846 u8 *programmed_state, u8 *current_state) 847 { 848 struct ti_sci_msg_resp_get_clock_state *resp; 849 struct ti_sci_msg_req_get_clock_state req; 850 struct ti_sci_info *info; 851 struct ti_sci_xfer *xfer; 852 int ret = 0; 853 854 if (IS_ERR(handle)) 855 return PTR_ERR(handle); 856 if (!handle) 857 return -EINVAL; 858 859 if (!programmed_state && !current_state) 860 return -EINVAL; 861 862 info = handle_to_ti_sci_info(handle); 863 864 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE, 865 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 866 (u32 *)&req, sizeof(req), sizeof(*resp)); 867 if (IS_ERR(xfer)) { 868 ret = PTR_ERR(xfer); 869 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 870 return ret; 871 } 872 req.dev_id = dev_id; 873 req.clk_id = clk_id; 874 875 ret = ti_sci_do_xfer(info, xfer); 876 if (ret) { 877 dev_err(info->dev, "Mbox send fail %d\n", ret); 878 return ret; 879 } 880 881 resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf; 882 883 if (!ti_sci_is_response_ack(resp)) 884 return -ENODEV; 885 886 if (programmed_state) 887 *programmed_state = resp->programmed_state; 888 if (current_state) 889 *current_state = resp->current_state; 890 891 return ret; 892 } 893 894 /** 895 * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI 896 * @handle: pointer to TI SCI handle 897 * @dev_id: Device identifier this request is for 898 * @clk_id: Clock identifier for the device for this request. 899 * Each device has it's own set of clock inputs. This indexes 900 * which clock input to modify. 901 * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false' 902 * @can_change_freq: 'true' if frequency change is desired, else 'false' 903 * @enable_input_term: 'true' if input termination is desired, else 'false' 904 * 905 * Return: 0 if all went well, else returns appropriate error value. 906 */ 907 static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id, 908 u8 clk_id, bool needs_ssc, bool can_change_freq, 909 bool enable_input_term) 910 { 911 u32 flags = 0; 912 913 flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0; 914 flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0; 915 flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0; 916 917 return ti_sci_set_clock_state(handle, dev_id, clk_id, flags, 918 MSG_CLOCK_SW_STATE_REQ); 919 } 920 921 /** 922 * ti_sci_cmd_idle_clock() - Idle a clock which is in our control 923 * @handle: pointer to TI SCI handle 924 * @dev_id: Device identifier this request is for 925 * @clk_id: Clock identifier for the device for this request. 926 * Each device has it's own set of clock inputs. This indexes 927 * which clock input to modify. 928 * 929 * NOTE: This clock must have been requested by get_clock previously. 930 * 931 * Return: 0 if all went well, else returns appropriate error value. 932 */ 933 static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle, 934 u32 dev_id, u8 clk_id) 935 { 936 return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, 937 MSG_CLOCK_SW_STATE_UNREQ); 938 } 939 940 /** 941 * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI 942 * @handle: pointer to TI SCI handle 943 * @dev_id: Device identifier this request is for 944 * @clk_id: Clock identifier for the device for this request. 945 * Each device has it's own set of clock inputs. This indexes 946 * which clock input to modify. 947 * 948 * NOTE: This clock must have been requested by get_clock previously. 949 * 950 * Return: 0 if all went well, else returns appropriate error value. 951 */ 952 static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle, 953 u32 dev_id, u8 clk_id) 954 { 955 return ti_sci_set_clock_state(handle, dev_id, clk_id, 0, 956 MSG_CLOCK_SW_STATE_AUTO); 957 } 958 959 /** 960 * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed 961 * @handle: pointer to TI SCI handle 962 * @dev_id: Device identifier this request is for 963 * @clk_id: Clock identifier for the device for this request. 964 * Each device has it's own set of clock inputs. This indexes 965 * which clock input to modify. 966 * @req_state: state indicating if the clock is auto managed 967 * 968 * Return: 0 if all went well, else returns appropriate error value. 969 */ 970 static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle, 971 u32 dev_id, u8 clk_id, bool *req_state) 972 { 973 u8 state = 0; 974 int ret; 975 976 if (!req_state) 977 return -EINVAL; 978 979 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL); 980 if (ret) 981 return ret; 982 983 *req_state = (state == MSG_CLOCK_SW_STATE_AUTO); 984 return 0; 985 } 986 987 /** 988 * ti_sci_cmd_clk_is_on() - Is the clock ON 989 * @handle: pointer to TI SCI handle 990 * @dev_id: Device identifier this request is for 991 * @clk_id: Clock identifier for the device for this request. 992 * Each device has it's own set of clock inputs. This indexes 993 * which clock input to modify. 994 * @req_state: state indicating if the clock is managed by us and enabled 995 * @curr_state: state indicating if the clock is ready for operation 996 * 997 * Return: 0 if all went well, else returns appropriate error value. 998 */ 999 static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id, 1000 u8 clk_id, bool *req_state, bool *curr_state) 1001 { 1002 u8 c_state = 0, r_state = 0; 1003 int ret; 1004 1005 if (!req_state && !curr_state) 1006 return -EINVAL; 1007 1008 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, 1009 &r_state, &c_state); 1010 if (ret) 1011 return ret; 1012 1013 if (req_state) 1014 *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ); 1015 if (curr_state) 1016 *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY); 1017 return 0; 1018 } 1019 1020 /** 1021 * ti_sci_cmd_clk_is_off() - Is the clock OFF 1022 * @handle: pointer to TI SCI handle 1023 * @dev_id: Device identifier this request is for 1024 * @clk_id: Clock identifier for the device for this request. 1025 * Each device has it's own set of clock inputs. This indexes 1026 * which clock input to modify. 1027 * @req_state: state indicating if the clock is managed by us and disabled 1028 * @curr_state: state indicating if the clock is NOT ready for operation 1029 * 1030 * Return: 0 if all went well, else returns appropriate error value. 1031 */ 1032 static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id, 1033 u8 clk_id, bool *req_state, bool *curr_state) 1034 { 1035 u8 c_state = 0, r_state = 0; 1036 int ret; 1037 1038 if (!req_state && !curr_state) 1039 return -EINVAL; 1040 1041 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, 1042 &r_state, &c_state); 1043 if (ret) 1044 return ret; 1045 1046 if (req_state) 1047 *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ); 1048 if (curr_state) 1049 *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY); 1050 return 0; 1051 } 1052 1053 /** 1054 * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock 1055 * @handle: pointer to TI SCI handle 1056 * @dev_id: Device identifier this request is for 1057 * @clk_id: Clock identifier for the device for this request. 1058 * Each device has it's own set of clock inputs. This indexes 1059 * which clock input to modify. 1060 * @parent_id: Parent clock identifier to set 1061 * 1062 * Return: 0 if all went well, else returns appropriate error value. 1063 */ 1064 static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, 1065 u32 dev_id, u8 clk_id, u8 parent_id) 1066 { 1067 struct ti_sci_msg_req_set_clock_parent req; 1068 struct ti_sci_msg_hdr *resp; 1069 struct ti_sci_info *info; 1070 struct ti_sci_xfer *xfer; 1071 int ret = 0; 1072 1073 if (IS_ERR(handle)) 1074 return PTR_ERR(handle); 1075 if (!handle) 1076 return -EINVAL; 1077 1078 info = handle_to_ti_sci_info(handle); 1079 1080 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT, 1081 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1082 (u32 *)&req, sizeof(req), sizeof(*resp)); 1083 if (IS_ERR(xfer)) { 1084 ret = PTR_ERR(xfer); 1085 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1086 return ret; 1087 } 1088 req.dev_id = dev_id; 1089 req.clk_id = clk_id; 1090 req.parent_id = parent_id; 1091 1092 ret = ti_sci_do_xfer(info, xfer); 1093 if (ret) { 1094 dev_err(info->dev, "Mbox send fail %d\n", ret); 1095 return ret; 1096 } 1097 1098 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1099 1100 if (!ti_sci_is_response_ack(resp)) 1101 return -ENODEV; 1102 1103 return ret; 1104 } 1105 1106 /** 1107 * ti_sci_cmd_clk_get_parent() - Get current parent clock source 1108 * @handle: pointer to TI SCI handle 1109 * @dev_id: Device identifier this request is for 1110 * @clk_id: Clock identifier for the device for this request. 1111 * Each device has it's own set of clock inputs. This indexes 1112 * which clock input to modify. 1113 * @parent_id: Current clock parent 1114 * 1115 * Return: 0 if all went well, else returns appropriate error value. 1116 */ 1117 static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, 1118 u32 dev_id, u8 clk_id, u8 *parent_id) 1119 { 1120 struct ti_sci_msg_resp_get_clock_parent *resp; 1121 struct ti_sci_msg_req_get_clock_parent req; 1122 struct ti_sci_info *info; 1123 struct ti_sci_xfer *xfer; 1124 int ret = 0; 1125 1126 if (IS_ERR(handle)) 1127 return PTR_ERR(handle); 1128 if (!handle || !parent_id) 1129 return -EINVAL; 1130 1131 info = handle_to_ti_sci_info(handle); 1132 1133 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT, 1134 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1135 (u32 *)&req, sizeof(req), sizeof(*resp)); 1136 if (IS_ERR(xfer)) { 1137 ret = PTR_ERR(xfer); 1138 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1139 return ret; 1140 } 1141 req.dev_id = dev_id; 1142 req.clk_id = clk_id; 1143 1144 ret = ti_sci_do_xfer(info, xfer); 1145 if (ret) { 1146 dev_err(info->dev, "Mbox send fail %d\n", ret); 1147 return ret; 1148 } 1149 1150 resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf; 1151 1152 if (!ti_sci_is_response_ack(resp)) 1153 ret = -ENODEV; 1154 else 1155 *parent_id = resp->parent_id; 1156 1157 return ret; 1158 } 1159 1160 /** 1161 * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source 1162 * @handle: pointer to TI SCI handle 1163 * @dev_id: Device identifier this request is for 1164 * @clk_id: Clock identifier for the device for this request. 1165 * Each device has it's own set of clock inputs. This indexes 1166 * which clock input to modify. 1167 * @num_parents: Returns he number of parents to the current clock. 1168 * 1169 * Return: 0 if all went well, else returns appropriate error value. 1170 */ 1171 static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, 1172 u32 dev_id, u8 clk_id, 1173 u8 *num_parents) 1174 { 1175 struct ti_sci_msg_resp_get_clock_num_parents *resp; 1176 struct ti_sci_msg_req_get_clock_num_parents req; 1177 struct ti_sci_info *info; 1178 struct ti_sci_xfer *xfer; 1179 int ret = 0; 1180 1181 if (IS_ERR(handle)) 1182 return PTR_ERR(handle); 1183 if (!handle || !num_parents) 1184 return -EINVAL; 1185 1186 info = handle_to_ti_sci_info(handle); 1187 1188 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, 1189 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1190 (u32 *)&req, sizeof(req), sizeof(*resp)); 1191 if (IS_ERR(xfer)) { 1192 ret = PTR_ERR(xfer); 1193 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1194 return ret; 1195 } 1196 req.dev_id = dev_id; 1197 req.clk_id = clk_id; 1198 1199 ret = ti_sci_do_xfer(info, xfer); 1200 if (ret) { 1201 dev_err(info->dev, "Mbox send fail %d\n", ret); 1202 return ret; 1203 } 1204 1205 resp = (struct ti_sci_msg_resp_get_clock_num_parents *) 1206 xfer->tx_message.buf; 1207 1208 if (!ti_sci_is_response_ack(resp)) 1209 ret = -ENODEV; 1210 else 1211 *num_parents = resp->num_parents; 1212 1213 return ret; 1214 } 1215 1216 /** 1217 * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency 1218 * @handle: pointer to TI SCI handle 1219 * @dev_id: Device identifier this request is for 1220 * @clk_id: Clock identifier for the device for this request. 1221 * Each device has it's own set of clock inputs. This indexes 1222 * which clock input to modify. 1223 * @min_freq: The minimum allowable frequency in Hz. This is the minimum 1224 * allowable programmed frequency and does not account for clock 1225 * tolerances and jitter. 1226 * @target_freq: The target clock frequency in Hz. A frequency will be 1227 * processed as close to this target frequency as possible. 1228 * @max_freq: The maximum allowable frequency in Hz. This is the maximum 1229 * allowable programmed frequency and does not account for clock 1230 * tolerances and jitter. 1231 * @match_freq: Frequency match in Hz response. 1232 * 1233 * Return: 0 if all went well, else returns appropriate error value. 1234 */ 1235 static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, 1236 u32 dev_id, u8 clk_id, u64 min_freq, 1237 u64 target_freq, u64 max_freq, 1238 u64 *match_freq) 1239 { 1240 struct ti_sci_msg_resp_query_clock_freq *resp; 1241 struct ti_sci_msg_req_query_clock_freq req; 1242 struct ti_sci_info *info; 1243 struct ti_sci_xfer *xfer; 1244 int ret = 0; 1245 1246 if (IS_ERR(handle)) 1247 return PTR_ERR(handle); 1248 if (!handle || !match_freq) 1249 return -EINVAL; 1250 1251 info = handle_to_ti_sci_info(handle); 1252 1253 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ, 1254 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1255 (u32 *)&req, sizeof(req), sizeof(*resp)); 1256 if (IS_ERR(xfer)) { 1257 ret = PTR_ERR(xfer); 1258 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1259 return ret; 1260 } 1261 req.dev_id = dev_id; 1262 req.clk_id = clk_id; 1263 req.min_freq_hz = min_freq; 1264 req.target_freq_hz = target_freq; 1265 req.max_freq_hz = max_freq; 1266 1267 ret = ti_sci_do_xfer(info, xfer); 1268 if (ret) { 1269 dev_err(info->dev, "Mbox send fail %d\n", ret); 1270 return ret; 1271 } 1272 1273 resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf; 1274 1275 if (!ti_sci_is_response_ack(resp)) 1276 ret = -ENODEV; 1277 else 1278 *match_freq = resp->freq_hz; 1279 1280 return ret; 1281 } 1282 1283 /** 1284 * ti_sci_cmd_clk_set_freq() - Set a frequency for clock 1285 * @handle: pointer to TI SCI handle 1286 * @dev_id: Device identifier this request is for 1287 * @clk_id: Clock identifier for the device for this request. 1288 * Each device has it's own set of clock inputs. This indexes 1289 * which clock input to modify. 1290 * @min_freq: The minimum allowable frequency in Hz. This is the minimum 1291 * allowable programmed frequency and does not account for clock 1292 * tolerances and jitter. 1293 * @target_freq: The target clock frequency in Hz. A frequency will be 1294 * processed as close to this target frequency as possible. 1295 * @max_freq: The maximum allowable frequency in Hz. This is the maximum 1296 * allowable programmed frequency and does not account for clock 1297 * tolerances and jitter. 1298 * 1299 * Return: 0 if all went well, else returns appropriate error value. 1300 */ 1301 static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, 1302 u32 dev_id, u8 clk_id, u64 min_freq, 1303 u64 target_freq, u64 max_freq) 1304 { 1305 struct ti_sci_msg_req_set_clock_freq req; 1306 struct ti_sci_msg_hdr *resp; 1307 struct ti_sci_info *info; 1308 struct ti_sci_xfer *xfer; 1309 int ret = 0; 1310 1311 if (IS_ERR(handle)) 1312 return PTR_ERR(handle); 1313 if (!handle) 1314 return -EINVAL; 1315 1316 info = handle_to_ti_sci_info(handle); 1317 1318 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ, 1319 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1320 (u32 *)&req, sizeof(req), sizeof(*resp)); 1321 if (IS_ERR(xfer)) { 1322 ret = PTR_ERR(xfer); 1323 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1324 return ret; 1325 } 1326 req.dev_id = dev_id; 1327 req.clk_id = clk_id; 1328 req.min_freq_hz = min_freq; 1329 req.target_freq_hz = target_freq; 1330 req.max_freq_hz = max_freq; 1331 1332 ret = ti_sci_do_xfer(info, xfer); 1333 if (ret) { 1334 dev_err(info->dev, "Mbox send fail %d\n", ret); 1335 return ret; 1336 } 1337 1338 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1339 1340 if (!ti_sci_is_response_ack(resp)) 1341 return -ENODEV; 1342 1343 return ret; 1344 } 1345 1346 /** 1347 * ti_sci_cmd_clk_get_freq() - Get current frequency 1348 * @handle: pointer to TI SCI handle 1349 * @dev_id: Device identifier this request is for 1350 * @clk_id: Clock identifier for the device for this request. 1351 * Each device has it's own set of clock inputs. This indexes 1352 * which clock input to modify. 1353 * @freq: Currently frequency in Hz 1354 * 1355 * Return: 0 if all went well, else returns appropriate error value. 1356 */ 1357 static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, 1358 u32 dev_id, u8 clk_id, u64 *freq) 1359 { 1360 struct ti_sci_msg_resp_get_clock_freq *resp; 1361 struct ti_sci_msg_req_get_clock_freq req; 1362 struct ti_sci_info *info; 1363 struct ti_sci_xfer *xfer; 1364 int ret = 0; 1365 1366 if (IS_ERR(handle)) 1367 return PTR_ERR(handle); 1368 if (!handle || !freq) 1369 return -EINVAL; 1370 1371 info = handle_to_ti_sci_info(handle); 1372 1373 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ, 1374 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1375 (u32 *)&req, sizeof(req), sizeof(*resp)); 1376 if (IS_ERR(xfer)) { 1377 ret = PTR_ERR(xfer); 1378 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1379 return ret; 1380 } 1381 req.dev_id = dev_id; 1382 req.clk_id = clk_id; 1383 1384 ret = ti_sci_do_xfer(info, xfer); 1385 if (ret) { 1386 dev_err(info->dev, "Mbox send fail %d\n", ret); 1387 return ret; 1388 } 1389 1390 resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf; 1391 1392 if (!ti_sci_is_response_ack(resp)) 1393 ret = -ENODEV; 1394 else 1395 *freq = resp->freq_hz; 1396 1397 return ret; 1398 } 1399 1400 /** 1401 * ti_sci_cmd_core_reboot() - Command to request system reset 1402 * @handle: pointer to TI SCI handle 1403 * 1404 * Return: 0 if all went well, else returns appropriate error value. 1405 */ 1406 static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) 1407 { 1408 struct ti_sci_msg_req_reboot req; 1409 struct ti_sci_msg_hdr *resp; 1410 struct ti_sci_info *info; 1411 struct ti_sci_xfer *xfer; 1412 int ret = 0; 1413 1414 if (IS_ERR(handle)) 1415 return PTR_ERR(handle); 1416 if (!handle) 1417 return -EINVAL; 1418 1419 info = handle_to_ti_sci_info(handle); 1420 1421 xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_SYS_RESET, 1422 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1423 (u32 *)&req, sizeof(req), sizeof(*resp)); 1424 if (IS_ERR(xfer)) { 1425 ret = PTR_ERR(xfer); 1426 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1427 return ret; 1428 } 1429 1430 ret = ti_sci_do_xfer(info, xfer); 1431 if (ret) { 1432 dev_err(dev, "Mbox send fail %d\n", ret); 1433 return ret; 1434 } 1435 1436 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1437 1438 if (!ti_sci_is_response_ack(resp)) 1439 return -ENODEV; 1440 1441 return ret; 1442 } 1443 1444 /** 1445 * ti_sci_cmd_proc_request() - Command to request a physical processor control 1446 * @handle: Pointer to TI SCI handle 1447 * @proc_id: Processor ID this request is for 1448 * 1449 * Return: 0 if all went well, else returns appropriate error value. 1450 */ 1451 static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, 1452 u8 proc_id) 1453 { 1454 struct ti_sci_msg_req_proc_request req; 1455 struct ti_sci_msg_hdr *resp; 1456 struct ti_sci_info *info; 1457 struct ti_sci_xfer *xfer; 1458 int ret = 0; 1459 1460 if (IS_ERR(handle)) 1461 return PTR_ERR(handle); 1462 if (!handle) 1463 return -EINVAL; 1464 1465 info = handle_to_ti_sci_info(handle); 1466 1467 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_REQUEST, 1468 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1469 (u32 *)&req, sizeof(req), sizeof(*resp)); 1470 if (IS_ERR(xfer)) { 1471 ret = PTR_ERR(xfer); 1472 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1473 return ret; 1474 } 1475 req.processor_id = proc_id; 1476 1477 ret = ti_sci_do_xfer(info, xfer); 1478 if (ret) { 1479 dev_err(info->dev, "Mbox send fail %d\n", ret); 1480 return ret; 1481 } 1482 1483 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1484 1485 if (!ti_sci_is_response_ack(resp)) 1486 ret = -ENODEV; 1487 1488 return ret; 1489 } 1490 1491 /** 1492 * ti_sci_cmd_proc_release() - Command to release a physical processor control 1493 * @handle: Pointer to TI SCI handle 1494 * @proc_id: Processor ID this request is for 1495 * 1496 * Return: 0 if all went well, else returns appropriate error value. 1497 */ 1498 static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, 1499 u8 proc_id) 1500 { 1501 struct ti_sci_msg_req_proc_release req; 1502 struct ti_sci_msg_hdr *resp; 1503 struct ti_sci_info *info; 1504 struct ti_sci_xfer *xfer; 1505 int ret = 0; 1506 1507 if (IS_ERR(handle)) 1508 return PTR_ERR(handle); 1509 if (!handle) 1510 return -EINVAL; 1511 1512 info = handle_to_ti_sci_info(handle); 1513 1514 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_RELEASE, 1515 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1516 (u32 *)&req, sizeof(req), sizeof(*resp)); 1517 if (IS_ERR(xfer)) { 1518 ret = PTR_ERR(xfer); 1519 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1520 return ret; 1521 } 1522 req.processor_id = proc_id; 1523 1524 ret = ti_sci_do_xfer(info, xfer); 1525 if (ret) { 1526 dev_err(info->dev, "Mbox send fail %d\n", ret); 1527 return ret; 1528 } 1529 1530 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1531 1532 if (!ti_sci_is_response_ack(resp)) 1533 ret = -ENODEV; 1534 1535 return ret; 1536 } 1537 1538 /** 1539 * ti_sci_cmd_proc_handover() - Command to handover a physical processor 1540 * control to a host in the processor's access 1541 * control list. 1542 * @handle: Pointer to TI SCI handle 1543 * @proc_id: Processor ID this request is for 1544 * @host_id: Host ID to get the control of the processor 1545 * 1546 * Return: 0 if all went well, else returns appropriate error value. 1547 */ 1548 static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, 1549 u8 proc_id, u8 host_id) 1550 { 1551 struct ti_sci_msg_req_proc_handover req; 1552 struct ti_sci_msg_hdr *resp; 1553 struct ti_sci_info *info; 1554 struct ti_sci_xfer *xfer; 1555 int ret = 0; 1556 1557 if (IS_ERR(handle)) 1558 return PTR_ERR(handle); 1559 if (!handle) 1560 return -EINVAL; 1561 1562 info = handle_to_ti_sci_info(handle); 1563 1564 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_HANDOVER, 1565 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1566 (u32 *)&req, sizeof(req), sizeof(*resp)); 1567 if (IS_ERR(xfer)) { 1568 ret = PTR_ERR(xfer); 1569 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1570 return ret; 1571 } 1572 req.processor_id = proc_id; 1573 req.host_id = host_id; 1574 1575 ret = ti_sci_do_xfer(info, xfer); 1576 if (ret) { 1577 dev_err(info->dev, "Mbox send fail %d\n", ret); 1578 return ret; 1579 } 1580 1581 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1582 1583 if (!ti_sci_is_response_ack(resp)) 1584 ret = -ENODEV; 1585 1586 return ret; 1587 } 1588 1589 /** 1590 * ti_sci_cmd_set_proc_boot_cfg() - Command to set the processor boot 1591 * configuration flags 1592 * @handle: Pointer to TI SCI handle 1593 * @proc_id: Processor ID this request is for 1594 * @config_flags_set: Configuration flags to be set 1595 * @config_flags_clear: Configuration flags to be cleared. 1596 * 1597 * Return: 0 if all went well, else returns appropriate error value. 1598 */ 1599 static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, 1600 u8 proc_id, u64 bootvector, 1601 u32 config_flags_set, 1602 u32 config_flags_clear) 1603 { 1604 struct ti_sci_msg_req_set_proc_boot_config req; 1605 struct ti_sci_msg_hdr *resp; 1606 struct ti_sci_info *info; 1607 struct ti_sci_xfer *xfer; 1608 int ret = 0; 1609 1610 if (IS_ERR(handle)) 1611 return PTR_ERR(handle); 1612 if (!handle) 1613 return -EINVAL; 1614 1615 info = handle_to_ti_sci_info(handle); 1616 1617 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CONFIG, 1618 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1619 (u32 *)&req, sizeof(req), sizeof(*resp)); 1620 if (IS_ERR(xfer)) { 1621 ret = PTR_ERR(xfer); 1622 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1623 return ret; 1624 } 1625 req.processor_id = proc_id; 1626 req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK; 1627 req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >> 1628 TISCI_ADDR_HIGH_SHIFT; 1629 req.config_flags_set = config_flags_set; 1630 req.config_flags_clear = config_flags_clear; 1631 1632 ret = ti_sci_do_xfer(info, xfer); 1633 if (ret) { 1634 dev_err(info->dev, "Mbox send fail %d\n", ret); 1635 return ret; 1636 } 1637 1638 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1639 1640 if (!ti_sci_is_response_ack(resp)) 1641 ret = -ENODEV; 1642 1643 return ret; 1644 } 1645 1646 /** 1647 * ti_sci_cmd_set_proc_boot_ctrl() - Command to set the processor boot 1648 * control flags 1649 * @handle: Pointer to TI SCI handle 1650 * @proc_id: Processor ID this request is for 1651 * @control_flags_set: Control flags to be set 1652 * @control_flags_clear: Control flags to be cleared 1653 * 1654 * Return: 0 if all went well, else returns appropriate error value. 1655 */ 1656 static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, 1657 u8 proc_id, u32 control_flags_set, 1658 u32 control_flags_clear) 1659 { 1660 struct ti_sci_msg_req_set_proc_boot_ctrl req; 1661 struct ti_sci_msg_hdr *resp; 1662 struct ti_sci_info *info; 1663 struct ti_sci_xfer *xfer; 1664 int ret = 0; 1665 1666 if (IS_ERR(handle)) 1667 return PTR_ERR(handle); 1668 if (!handle) 1669 return -EINVAL; 1670 1671 info = handle_to_ti_sci_info(handle); 1672 1673 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_SET_PROC_BOOT_CTRL, 1674 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1675 (u32 *)&req, sizeof(req), sizeof(*resp)); 1676 if (IS_ERR(xfer)) { 1677 ret = PTR_ERR(xfer); 1678 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1679 return ret; 1680 } 1681 req.processor_id = proc_id; 1682 req.control_flags_set = control_flags_set; 1683 req.control_flags_clear = control_flags_clear; 1684 1685 ret = ti_sci_do_xfer(info, xfer); 1686 if (ret) { 1687 dev_err(info->dev, "Mbox send fail %d\n", ret); 1688 return ret; 1689 } 1690 1691 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1692 1693 if (!ti_sci_is_response_ack(resp)) 1694 ret = -ENODEV; 1695 1696 return ret; 1697 } 1698 1699 /** 1700 * ti_sci_cmd_proc_auth_boot_image() - Command to authenticate and load the 1701 * image and then set the processor configuration flags. 1702 * @handle: Pointer to TI SCI handle 1703 * @proc_id: Processor ID this request is for 1704 * @cert_addr: Memory address at which payload image certificate is located. 1705 * 1706 * Return: 0 if all went well, else returns appropriate error value. 1707 */ 1708 static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, 1709 u8 proc_id, u64 cert_addr) 1710 { 1711 struct ti_sci_msg_req_proc_auth_boot_image req; 1712 struct ti_sci_msg_hdr *resp; 1713 struct ti_sci_info *info; 1714 struct ti_sci_xfer *xfer; 1715 int ret = 0; 1716 1717 if (IS_ERR(handle)) 1718 return PTR_ERR(handle); 1719 if (!handle) 1720 return -EINVAL; 1721 1722 info = handle_to_ti_sci_info(handle); 1723 1724 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_PROC_AUTH_BOOT_IMIAGE, 1725 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1726 (u32 *)&req, sizeof(req), sizeof(*resp)); 1727 if (IS_ERR(xfer)) { 1728 ret = PTR_ERR(xfer); 1729 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1730 return ret; 1731 } 1732 req.processor_id = proc_id; 1733 req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK; 1734 req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >> 1735 TISCI_ADDR_HIGH_SHIFT; 1736 1737 ret = ti_sci_do_xfer(info, xfer); 1738 if (ret) { 1739 dev_err(info->dev, "Mbox send fail %d\n", ret); 1740 return ret; 1741 } 1742 1743 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 1744 1745 if (!ti_sci_is_response_ack(resp)) 1746 ret = -ENODEV; 1747 1748 return ret; 1749 } 1750 1751 /** 1752 * ti_sci_cmd_get_proc_boot_status() - Command to get the processor boot status 1753 * @handle: Pointer to TI SCI handle 1754 * @proc_id: Processor ID this request is for 1755 * 1756 * Return: 0 if all went well, else returns appropriate error value. 1757 */ 1758 static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, 1759 u8 proc_id, u64 *bv, u32 *cfg_flags, 1760 u32 *ctrl_flags, u32 *sts_flags) 1761 { 1762 struct ti_sci_msg_resp_get_proc_boot_status *resp; 1763 struct ti_sci_msg_req_get_proc_boot_status req; 1764 struct ti_sci_info *info; 1765 struct ti_sci_xfer *xfer; 1766 int ret = 0; 1767 1768 if (IS_ERR(handle)) 1769 return PTR_ERR(handle); 1770 if (!handle) 1771 return -EINVAL; 1772 1773 info = handle_to_ti_sci_info(handle); 1774 1775 xfer = ti_sci_setup_one_xfer(info, TISCI_MSG_GET_PROC_BOOT_STATUS, 1776 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1777 (u32 *)&req, sizeof(req), sizeof(*resp)); 1778 if (IS_ERR(xfer)) { 1779 ret = PTR_ERR(xfer); 1780 dev_err(info->dev, "Message alloc failed(%d)\n", ret); 1781 return ret; 1782 } 1783 req.processor_id = proc_id; 1784 1785 ret = ti_sci_do_xfer(info, xfer); 1786 if (ret) { 1787 dev_err(info->dev, "Mbox send fail %d\n", ret); 1788 return ret; 1789 } 1790 1791 resp = (struct ti_sci_msg_resp_get_proc_boot_status *) 1792 xfer->tx_message.buf; 1793 1794 if (!ti_sci_is_response_ack(resp)) 1795 return -ENODEV; 1796 *bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) | 1797 (((u64)resp->bootvector_high << 1798 TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); 1799 *cfg_flags = resp->config_flags; 1800 *ctrl_flags = resp->control_flags; 1801 *sts_flags = resp->status_flags; 1802 1803 return ret; 1804 } 1805 1806 /* 1807 * ti_sci_setup_ops() - Setup the operations structures 1808 * @info: pointer to TISCI pointer 1809 */ 1810 static void ti_sci_setup_ops(struct ti_sci_info *info) 1811 { 1812 struct ti_sci_ops *ops = &info->handle.ops; 1813 struct ti_sci_board_ops *bops = &ops->board_ops; 1814 struct ti_sci_dev_ops *dops = &ops->dev_ops; 1815 struct ti_sci_clk_ops *cops = &ops->clk_ops; 1816 struct ti_sci_core_ops *core_ops = &ops->core_ops; 1817 struct ti_sci_proc_ops *pops = &ops->proc_ops; 1818 1819 bops->board_config = ti_sci_cmd_set_board_config; 1820 bops->board_config_rm = ti_sci_cmd_set_board_config_rm; 1821 bops->board_config_security = ti_sci_cmd_set_board_config_security; 1822 bops->board_config_pm = ti_sci_cmd_set_board_config_pm; 1823 1824 dops->get_device = ti_sci_cmd_get_device; 1825 dops->idle_device = ti_sci_cmd_idle_device; 1826 dops->put_device = ti_sci_cmd_put_device; 1827 dops->is_valid = ti_sci_cmd_dev_is_valid; 1828 dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt; 1829 dops->is_idle = ti_sci_cmd_dev_is_idle; 1830 dops->is_stop = ti_sci_cmd_dev_is_stop; 1831 dops->is_on = ti_sci_cmd_dev_is_on; 1832 dops->is_transitioning = ti_sci_cmd_dev_is_trans; 1833 dops->set_device_resets = ti_sci_cmd_set_device_resets; 1834 dops->get_device_resets = ti_sci_cmd_get_device_resets; 1835 1836 cops->get_clock = ti_sci_cmd_get_clock; 1837 cops->idle_clock = ti_sci_cmd_idle_clock; 1838 cops->put_clock = ti_sci_cmd_put_clock; 1839 cops->is_auto = ti_sci_cmd_clk_is_auto; 1840 cops->is_on = ti_sci_cmd_clk_is_on; 1841 cops->is_off = ti_sci_cmd_clk_is_off; 1842 1843 cops->set_parent = ti_sci_cmd_clk_set_parent; 1844 cops->get_parent = ti_sci_cmd_clk_get_parent; 1845 cops->get_num_parents = ti_sci_cmd_clk_get_num_parents; 1846 1847 cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; 1848 cops->set_freq = ti_sci_cmd_clk_set_freq; 1849 cops->get_freq = ti_sci_cmd_clk_get_freq; 1850 1851 core_ops->reboot_device = ti_sci_cmd_core_reboot; 1852 1853 pops->proc_request = ti_sci_cmd_proc_request; 1854 pops->proc_release = ti_sci_cmd_proc_release; 1855 pops->proc_handover = ti_sci_cmd_proc_handover; 1856 pops->set_proc_boot_cfg = ti_sci_cmd_set_proc_boot_cfg; 1857 pops->set_proc_boot_ctrl = ti_sci_cmd_set_proc_boot_ctrl; 1858 pops->proc_auth_boot_image = ti_sci_cmd_proc_auth_boot_image; 1859 pops->get_proc_boot_status = ti_sci_cmd_get_proc_boot_status; 1860 } 1861 1862 /** 1863 * ti_sci_get_handle_from_sysfw() - Get the TI SCI handle of the SYSFW 1864 * @dev: Pointer to the SYSFW device 1865 * 1866 * Return: pointer to handle if successful, else EINVAL if invalid conditions 1867 * are encountered. 1868 */ 1869 const 1870 struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *sci_dev) 1871 { 1872 if (!sci_dev) 1873 return ERR_PTR(-EINVAL); 1874 1875 struct ti_sci_info *info = dev_get_priv(sci_dev); 1876 1877 if (!info) 1878 return ERR_PTR(-EINVAL); 1879 1880 struct ti_sci_handle *handle = &info->handle; 1881 1882 if (!handle) 1883 return ERR_PTR(-EINVAL); 1884 1885 return handle; 1886 } 1887 1888 /** 1889 * ti_sci_get_handle() - Get the TI SCI handle for a device 1890 * @dev: Pointer to device for which we want SCI handle 1891 * 1892 * Return: pointer to handle if successful, else EINVAL if invalid conditions 1893 * are encountered. 1894 */ 1895 const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev) 1896 { 1897 if (!dev) 1898 return ERR_PTR(-EINVAL); 1899 1900 struct udevice *sci_dev = dev_get_parent(dev); 1901 1902 return ti_sci_get_handle_from_sysfw(sci_dev); 1903 } 1904 1905 /** 1906 * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle 1907 * @dev: device node 1908 * @propname: property name containing phandle on TISCI node 1909 * 1910 * Return: pointer to handle if successful, else appropriate error value. 1911 */ 1912 const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev, 1913 const char *property) 1914 { 1915 struct ti_sci_info *entry, *info = NULL; 1916 u32 phandle, err; 1917 ofnode node; 1918 1919 err = ofnode_read_u32(dev_ofnode(dev), property, &phandle); 1920 if (err) 1921 return ERR_PTR(err); 1922 1923 node = ofnode_get_by_phandle(phandle); 1924 if (!ofnode_valid(node)) 1925 return ERR_PTR(-EINVAL); 1926 1927 list_for_each_entry(entry, &ti_sci_list, list) 1928 if (ofnode_equal(dev_ofnode(entry->dev), node)) { 1929 info = entry; 1930 break; 1931 } 1932 1933 if (!info) 1934 return ERR_PTR(-ENODEV); 1935 1936 return &info->handle; 1937 } 1938 1939 /** 1940 * ti_sci_of_to_info() - generate private data from device tree 1941 * @dev: corresponding system controller interface device 1942 * @info: pointer to driver specific private data 1943 * 1944 * Return: 0 if all goes good, else appropriate error message. 1945 */ 1946 static int ti_sci_of_to_info(struct udevice *dev, struct ti_sci_info *info) 1947 { 1948 int ret; 1949 1950 ret = mbox_get_by_name(dev, "tx", &info->chan_tx); 1951 if (ret) { 1952 dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n", 1953 __func__, ret); 1954 return ret; 1955 } 1956 1957 ret = mbox_get_by_name(dev, "rx", &info->chan_rx); 1958 if (ret) { 1959 dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n", 1960 __func__, ret); 1961 return ret; 1962 } 1963 1964 /* Notify channel is optional. Enable only if populated */ 1965 ret = mbox_get_by_name(dev, "notify", &info->chan_notify); 1966 if (ret) { 1967 dev_dbg(dev, "%s: Acquiring notify channel failed. ret = %d\n", 1968 __func__, ret); 1969 } 1970 1971 info->host_id = dev_read_u32_default(dev, "ti,host-id", 1972 info->desc->host_id); 1973 1974 info->is_secure = dev_read_bool(dev, "ti,secure-host"); 1975 1976 return 0; 1977 } 1978 1979 /** 1980 * ti_sci_probe() - Basic probe 1981 * @dev: corresponding system controller interface device 1982 * 1983 * Return: 0 if all goes good, else appropriate error message. 1984 */ 1985 static int ti_sci_probe(struct udevice *dev) 1986 { 1987 struct ti_sci_info *info; 1988 int ret; 1989 1990 debug("%s(dev=%p)\n", __func__, dev); 1991 1992 info = dev_get_priv(dev); 1993 info->desc = (void *)dev_get_driver_data(dev); 1994 1995 ret = ti_sci_of_to_info(dev, info); 1996 if (ret) { 1997 dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret); 1998 return ret; 1999 } 2000 2001 info->dev = dev; 2002 info->seq = 0xA; 2003 2004 list_add_tail(&info->list, &ti_sci_list); 2005 ti_sci_setup_ops(info); 2006 2007 ret = ti_sci_cmd_get_revision(&info->handle); 2008 2009 return ret; 2010 } 2011 2012 /* Description for AM654 */ 2013 static const struct ti_sci_desc ti_sci_sysfw_am654_desc = { 2014 .host_id = 4, 2015 .max_rx_timeout_us = 1000000, 2016 .max_msg_size = 60, 2017 }; 2018 2019 static const struct udevice_id ti_sci_ids[] = { 2020 { 2021 .compatible = "ti,k2g-sci", 2022 .data = (ulong)&ti_sci_sysfw_am654_desc 2023 }, 2024 { /* Sentinel */ }, 2025 }; 2026 2027 U_BOOT_DRIVER(ti_sci) = { 2028 .name = "ti_sci", 2029 .id = UCLASS_FIRMWARE, 2030 .of_match = ti_sci_ids, 2031 .probe = ti_sci_probe, 2032 .priv_auto_alloc_size = sizeof(struct ti_sci_info), 2033 }; 2034