1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Texas Instruments System Control Interface Protocol Driver 4 * 5 * Copyright (C) 2015-2022 Texas Instruments Incorporated - https://www.ti.com/ 6 * Nishanth Menon 7 */ 8 9 #define pr_fmt(fmt) "%s: " fmt, __func__ 10 11 #include <linux/bitmap.h> 12 #include <linux/debugfs.h> 13 #include <linux/export.h> 14 #include <linux/io.h> 15 #include <linux/iopoll.h> 16 #include <linux/kernel.h> 17 #include <linux/mailbox_client.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/of_platform.h> 21 #include <linux/platform_device.h> 22 #include <linux/property.h> 23 #include <linux/semaphore.h> 24 #include <linux/slab.h> 25 #include <linux/soc/ti/ti-msgmgr.h> 26 #include <linux/soc/ti/ti_sci_protocol.h> 27 #include <linux/reboot.h> 28 29 #include "ti_sci.h" 30 31 /* List of all TI SCI devices active in system */ 32 static LIST_HEAD(ti_sci_list); 33 /* Protection for the entire list */ 34 static DEFINE_MUTEX(ti_sci_list_mutex); 35 36 /** 37 * struct ti_sci_xfer - Structure representing a message flow 38 * @tx_message: Transmit message 39 * @rx_len: Receive message length 40 * @xfer_buf: Preallocated buffer to store receive message 41 * Since we work with request-ACK protocol, we can 42 * reuse the same buffer for the rx path as we 43 * use for the tx path. 44 * @done: completion event 45 */ 46 struct ti_sci_xfer { 47 struct ti_msgmgr_message tx_message; 48 u8 rx_len; 49 u8 *xfer_buf; 50 struct completion done; 51 }; 52 53 /** 54 * struct ti_sci_xfers_info - Structure to manage transfer information 55 * @sem_xfer_count: Counting Semaphore for managing max simultaneous 56 * Messages. 57 * @xfer_block: Preallocated Message array 58 * @xfer_alloc_table: Bitmap table for allocated messages. 59 * Index of this bitmap table is also used for message 60 * sequence identifier. 61 * @xfer_lock: Protection for message allocation 62 */ 63 struct ti_sci_xfers_info { 64 struct semaphore sem_xfer_count; 65 struct ti_sci_xfer *xfer_block; 66 unsigned long *xfer_alloc_table; 67 /* protect transfer allocation */ 68 spinlock_t xfer_lock; 69 }; 70 71 /** 72 * struct ti_sci_desc - Description of SoC integration 73 * @default_host_id: Host identifier representing the compute entity 74 * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds) 75 * @max_msgs: Maximum number of messages that can be pending 76 * simultaneously in the system 77 * @max_msg_size: Maximum size of data per message that can be handled. 78 */ 79 struct ti_sci_desc { 80 u8 default_host_id; 81 int max_rx_timeout_ms; 82 int max_msgs; 83 int max_msg_size; 84 }; 85 86 /** 87 * struct ti_sci_info - Structure representing a TI SCI instance 88 * @dev: Device pointer 89 * @desc: SoC description for this instance 90 * @nb: Reboot Notifier block 91 * @d: Debugfs file entry 92 * @debug_region: Memory region where the debug message are available 93 * @debug_region_size: Debug region size 94 * @debug_buffer: Buffer allocated to copy debug messages. 95 * @handle: Instance of TI SCI handle to send to clients. 96 * @cl: Mailbox Client 97 * @chan_tx: Transmit mailbox channel 98 * @chan_rx: Receive mailbox channel 99 * @minfo: Message info 100 * @node: list head 101 * @host_id: Host ID 102 * @users: Number of users of this instance 103 */ 104 struct ti_sci_info { 105 struct device *dev; 106 struct notifier_block nb; 107 const struct ti_sci_desc *desc; 108 struct dentry *d; 109 void __iomem *debug_region; 110 char *debug_buffer; 111 size_t debug_region_size; 112 struct ti_sci_handle handle; 113 struct mbox_client cl; 114 struct mbox_chan *chan_tx; 115 struct mbox_chan *chan_rx; 116 struct ti_sci_xfers_info minfo; 117 struct list_head node; 118 u8 host_id; 119 /* protected by ti_sci_list_mutex */ 120 int users; 121 }; 122 123 #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl) 124 #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle) 125 #define reboot_to_ti_sci_info(n) container_of(n, struct ti_sci_info, nb) 126 127 #ifdef CONFIG_DEBUG_FS 128 129 /** 130 * ti_sci_debug_show() - Helper to dump the debug log 131 * @s: sequence file pointer 132 * @unused: unused. 133 * 134 * Return: 0 135 */ 136 static int ti_sci_debug_show(struct seq_file *s, void *unused) 137 { 138 struct ti_sci_info *info = s->private; 139 140 memcpy_fromio(info->debug_buffer, info->debug_region, 141 info->debug_region_size); 142 /* 143 * We don't trust firmware to leave NULL terminated last byte (hence 144 * we have allocated 1 extra 0 byte). Since we cannot guarantee any 145 * specific data format for debug messages, We just present the data 146 * in the buffer as is - we expect the messages to be self explanatory. 147 */ 148 seq_puts(s, info->debug_buffer); 149 return 0; 150 } 151 152 /* Provide the log file operations interface*/ 153 DEFINE_SHOW_ATTRIBUTE(ti_sci_debug); 154 155 /** 156 * ti_sci_debugfs_create() - Create log debug file 157 * @pdev: platform device pointer 158 * @info: Pointer to SCI entity information 159 * 160 * Return: 0 if all went fine, else corresponding error. 161 */ 162 static int ti_sci_debugfs_create(struct platform_device *pdev, 163 struct ti_sci_info *info) 164 { 165 struct device *dev = &pdev->dev; 166 struct resource *res; 167 char debug_name[50]; 168 169 /* Debug region is optional */ 170 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 171 "debug_messages"); 172 info->debug_region = devm_ioremap_resource(dev, res); 173 if (IS_ERR(info->debug_region)) 174 return 0; 175 info->debug_region_size = resource_size(res); 176 177 info->debug_buffer = devm_kcalloc(dev, info->debug_region_size + 1, 178 sizeof(char), GFP_KERNEL); 179 if (!info->debug_buffer) 180 return -ENOMEM; 181 /* Setup NULL termination */ 182 info->debug_buffer[info->debug_region_size] = 0; 183 184 snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s", 185 dev_name(dev)); 186 info->d = debugfs_create_file(debug_name, 0444, NULL, info, 187 &ti_sci_debug_fops); 188 if (IS_ERR(info->d)) 189 return PTR_ERR(info->d); 190 191 dev_dbg(dev, "Debug region => %p, size = %zu bytes, resource: %pr\n", 192 info->debug_region, info->debug_region_size, res); 193 return 0; 194 } 195 196 #else /* CONFIG_DEBUG_FS */ 197 static inline int ti_sci_debugfs_create(struct platform_device *dev, 198 struct ti_sci_info *info) 199 { 200 return 0; 201 } 202 203 static inline void ti_sci_debugfs_destroy(struct platform_device *dev, 204 struct ti_sci_info *info) 205 { 206 } 207 #endif /* CONFIG_DEBUG_FS */ 208 209 /** 210 * ti_sci_dump_header_dbg() - Helper to dump a message header. 211 * @dev: Device pointer corresponding to the SCI entity 212 * @hdr: pointer to header. 213 */ 214 static inline void ti_sci_dump_header_dbg(struct device *dev, 215 struct ti_sci_msg_hdr *hdr) 216 { 217 dev_dbg(dev, "MSGHDR:type=0x%04x host=0x%02x seq=0x%02x flags=0x%08x\n", 218 hdr->type, hdr->host, hdr->seq, hdr->flags); 219 } 220 221 /** 222 * ti_sci_rx_callback() - mailbox client callback for receive messages 223 * @cl: client pointer 224 * @m: mailbox message 225 * 226 * Processes one received message to appropriate transfer information and 227 * signals completion of the transfer. 228 * 229 * NOTE: This function will be invoked in IRQ context, hence should be 230 * as optimal as possible. 231 */ 232 static void ti_sci_rx_callback(struct mbox_client *cl, void *m) 233 { 234 struct ti_sci_info *info = cl_to_ti_sci_info(cl); 235 struct device *dev = info->dev; 236 struct ti_sci_xfers_info *minfo = &info->minfo; 237 struct ti_msgmgr_message *mbox_msg = m; 238 struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)mbox_msg->buf; 239 struct ti_sci_xfer *xfer; 240 u8 xfer_id; 241 242 xfer_id = hdr->seq; 243 244 /* 245 * Are we even expecting this? 246 * NOTE: barriers were implicit in locks used for modifying the bitmap 247 */ 248 if (!test_bit(xfer_id, minfo->xfer_alloc_table)) { 249 dev_err(dev, "Message for %d is not expected!\n", xfer_id); 250 return; 251 } 252 253 xfer = &minfo->xfer_block[xfer_id]; 254 255 /* Is the message of valid length? */ 256 if (mbox_msg->len > info->desc->max_msg_size) { 257 dev_err(dev, "Unable to handle %zu xfer(max %d)\n", 258 mbox_msg->len, info->desc->max_msg_size); 259 ti_sci_dump_header_dbg(dev, hdr); 260 return; 261 } 262 if (mbox_msg->len < xfer->rx_len) { 263 dev_err(dev, "Recv xfer %zu < expected %d length\n", 264 mbox_msg->len, xfer->rx_len); 265 ti_sci_dump_header_dbg(dev, hdr); 266 return; 267 } 268 269 ti_sci_dump_header_dbg(dev, hdr); 270 /* Take a copy to the rx buffer.. */ 271 memcpy(xfer->xfer_buf, mbox_msg->buf, xfer->rx_len); 272 complete(&xfer->done); 273 } 274 275 /** 276 * ti_sci_get_one_xfer() - Allocate one message 277 * @info: Pointer to SCI entity information 278 * @msg_type: Message type 279 * @msg_flags: Flag to set for the message 280 * @tx_message_size: transmit message size 281 * @rx_message_size: receive message size 282 * 283 * Helper function which is used by various command functions that are 284 * exposed to clients of this driver for allocating a message traffic event. 285 * 286 * This function can sleep depending on pending requests already in the system 287 * for the SCI entity. Further, this also holds a spinlock to maintain integrity 288 * of internal data structures. 289 * 290 * Return: 0 if all went fine, else corresponding error. 291 */ 292 static struct ti_sci_xfer *ti_sci_get_one_xfer(struct ti_sci_info *info, 293 u16 msg_type, u32 msg_flags, 294 size_t tx_message_size, 295 size_t rx_message_size) 296 { 297 struct ti_sci_xfers_info *minfo = &info->minfo; 298 struct ti_sci_xfer *xfer; 299 struct ti_sci_msg_hdr *hdr; 300 unsigned long flags; 301 unsigned long bit_pos; 302 u8 xfer_id; 303 int ret; 304 int timeout; 305 306 /* Ensure we have sane transfer sizes */ 307 if (rx_message_size > info->desc->max_msg_size || 308 tx_message_size > info->desc->max_msg_size || 309 rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr)) 310 return ERR_PTR(-ERANGE); 311 312 /* 313 * Ensure we have only controlled number of pending messages. 314 * Ideally, we might just have to wait a single message, be 315 * conservative and wait 5 times that.. 316 */ 317 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms) * 5; 318 ret = down_timeout(&minfo->sem_xfer_count, timeout); 319 if (ret < 0) 320 return ERR_PTR(ret); 321 322 /* Keep the locked section as small as possible */ 323 spin_lock_irqsave(&minfo->xfer_lock, flags); 324 bit_pos = find_first_zero_bit(minfo->xfer_alloc_table, 325 info->desc->max_msgs); 326 set_bit(bit_pos, minfo->xfer_alloc_table); 327 spin_unlock_irqrestore(&minfo->xfer_lock, flags); 328 329 /* 330 * We already ensured in probe that we can have max messages that can 331 * fit in hdr.seq - NOTE: this improves access latencies 332 * to predictable O(1) access, BUT, it opens us to risk if 333 * remote misbehaves with corrupted message sequence responses. 334 * If that happens, we are going to be messed up anyways.. 335 */ 336 xfer_id = (u8)bit_pos; 337 338 xfer = &minfo->xfer_block[xfer_id]; 339 340 hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 341 xfer->tx_message.len = tx_message_size; 342 xfer->tx_message.chan_rx = info->chan_rx; 343 xfer->tx_message.timeout_rx_ms = info->desc->max_rx_timeout_ms; 344 xfer->rx_len = (u8)rx_message_size; 345 346 reinit_completion(&xfer->done); 347 348 hdr->seq = xfer_id; 349 hdr->type = msg_type; 350 hdr->host = info->host_id; 351 hdr->flags = msg_flags; 352 353 return xfer; 354 } 355 356 /** 357 * ti_sci_put_one_xfer() - Release a message 358 * @minfo: transfer info pointer 359 * @xfer: message that was reserved by ti_sci_get_one_xfer 360 * 361 * This holds a spinlock to maintain integrity of internal data structures. 362 */ 363 static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo, 364 struct ti_sci_xfer *xfer) 365 { 366 unsigned long flags; 367 struct ti_sci_msg_hdr *hdr; 368 u8 xfer_id; 369 370 hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 371 xfer_id = hdr->seq; 372 373 /* 374 * Keep the locked section as small as possible 375 * NOTE: we might escape with smp_mb and no lock here.. 376 * but just be conservative and symmetric. 377 */ 378 spin_lock_irqsave(&minfo->xfer_lock, flags); 379 clear_bit(xfer_id, minfo->xfer_alloc_table); 380 spin_unlock_irqrestore(&minfo->xfer_lock, flags); 381 382 /* Increment the count for the next user to get through */ 383 up(&minfo->sem_xfer_count); 384 } 385 386 /** 387 * ti_sci_do_xfer() - Do one transfer 388 * @info: Pointer to SCI entity information 389 * @xfer: Transfer to initiate and wait for response 390 * 391 * Return: -ETIMEDOUT in case of no response, if transmit error, 392 * return corresponding error, else if all goes well, 393 * return 0. 394 */ 395 static inline int ti_sci_do_xfer(struct ti_sci_info *info, 396 struct ti_sci_xfer *xfer) 397 { 398 int ret; 399 int timeout; 400 struct device *dev = info->dev; 401 bool done_state = true; 402 403 ret = mbox_send_message(info->chan_tx, &xfer->tx_message); 404 if (ret < 0) 405 return ret; 406 407 ret = 0; 408 409 if (system_state <= SYSTEM_RUNNING) { 410 /* And we wait for the response. */ 411 timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms); 412 if (!wait_for_completion_timeout(&xfer->done, timeout)) 413 ret = -ETIMEDOUT; 414 } else { 415 /* 416 * If we are !running, we cannot use wait_for_completion_timeout 417 * during noirq phase, so we must manually poll the completion. 418 */ 419 ret = read_poll_timeout_atomic(try_wait_for_completion, done_state, 420 done_state, 1, 421 info->desc->max_rx_timeout_ms * 1000, 422 false, &xfer->done); 423 } 424 425 if (ret == -ETIMEDOUT) 426 dev_err(dev, "Mbox timedout in resp(caller: %pS)\n", 427 (void *)_RET_IP_); 428 429 /* 430 * NOTE: we might prefer not to need the mailbox ticker to manage the 431 * transfer queueing since the protocol layer queues things by itself. 432 * Unfortunately, we have to kick the mailbox framework after we have 433 * received our message. 434 */ 435 mbox_client_txdone(info->chan_tx, ret); 436 437 return ret; 438 } 439 440 /** 441 * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity 442 * @info: Pointer to SCI entity information 443 * 444 * Updates the SCI information in the internal data structure. 445 * 446 * Return: 0 if all went fine, else return appropriate error. 447 */ 448 static int ti_sci_cmd_get_revision(struct ti_sci_info *info) 449 { 450 struct device *dev = info->dev; 451 struct ti_sci_handle *handle = &info->handle; 452 struct ti_sci_version_info *ver = &handle->version; 453 struct ti_sci_msg_resp_version *rev_info; 454 struct ti_sci_xfer *xfer; 455 int ret; 456 457 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_VERSION, 458 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 459 sizeof(struct ti_sci_msg_hdr), 460 sizeof(*rev_info)); 461 if (IS_ERR(xfer)) { 462 ret = PTR_ERR(xfer); 463 dev_err(dev, "Message alloc failed(%d)\n", ret); 464 return ret; 465 } 466 467 rev_info = (struct ti_sci_msg_resp_version *)xfer->xfer_buf; 468 469 ret = ti_sci_do_xfer(info, xfer); 470 if (ret) { 471 dev_err(dev, "Mbox send fail %d\n", ret); 472 goto fail; 473 } 474 475 ver->abi_major = rev_info->abi_major; 476 ver->abi_minor = rev_info->abi_minor; 477 ver->firmware_revision = rev_info->firmware_revision; 478 strscpy(ver->firmware_description, rev_info->firmware_description, 479 sizeof(ver->firmware_description)); 480 481 fail: 482 ti_sci_put_one_xfer(&info->minfo, xfer); 483 return ret; 484 } 485 486 /** 487 * ti_sci_is_response_ack() - Generic ACK/NACK message checkup 488 * @r: pointer to response buffer 489 * 490 * Return: true if the response was an ACK, else returns false. 491 */ 492 static inline bool ti_sci_is_response_ack(void *r) 493 { 494 struct ti_sci_msg_hdr *hdr = r; 495 496 return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; 497 } 498 499 /** 500 * ti_sci_set_device_state() - Set device state helper 501 * @handle: pointer to TI SCI handle 502 * @id: Device identifier 503 * @flags: flags to setup for the device 504 * @state: State to move the device to 505 * 506 * Return: 0 if all went well, else returns appropriate error value. 507 */ 508 static int ti_sci_set_device_state(const struct ti_sci_handle *handle, 509 u32 id, u32 flags, u8 state) 510 { 511 struct ti_sci_info *info; 512 struct ti_sci_msg_req_set_device_state *req; 513 struct ti_sci_msg_hdr *resp; 514 struct ti_sci_xfer *xfer; 515 struct device *dev; 516 int ret = 0; 517 518 if (IS_ERR(handle)) 519 return PTR_ERR(handle); 520 if (!handle) 521 return -EINVAL; 522 523 info = handle_to_ti_sci_info(handle); 524 dev = info->dev; 525 526 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_STATE, 527 flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 528 sizeof(*req), sizeof(*resp)); 529 if (IS_ERR(xfer)) { 530 ret = PTR_ERR(xfer); 531 dev_err(dev, "Message alloc failed(%d)\n", ret); 532 return ret; 533 } 534 req = (struct ti_sci_msg_req_set_device_state *)xfer->xfer_buf; 535 req->id = id; 536 req->state = state; 537 538 ret = ti_sci_do_xfer(info, xfer); 539 if (ret) { 540 dev_err(dev, "Mbox send fail %d\n", ret); 541 goto fail; 542 } 543 544 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 545 546 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 547 548 fail: 549 ti_sci_put_one_xfer(&info->minfo, xfer); 550 551 return ret; 552 } 553 554 /** 555 * ti_sci_get_device_state() - Get device state helper 556 * @handle: Handle to the device 557 * @id: Device Identifier 558 * @clcnt: Pointer to Context Loss Count 559 * @resets: pointer to resets 560 * @p_state: pointer to p_state 561 * @c_state: pointer to c_state 562 * 563 * Return: 0 if all went fine, else return appropriate error. 564 */ 565 static int ti_sci_get_device_state(const struct ti_sci_handle *handle, 566 u32 id, u32 *clcnt, u32 *resets, 567 u8 *p_state, u8 *c_state) 568 { 569 struct ti_sci_info *info; 570 struct ti_sci_msg_req_get_device_state *req; 571 struct ti_sci_msg_resp_get_device_state *resp; 572 struct ti_sci_xfer *xfer; 573 struct device *dev; 574 int ret = 0; 575 576 if (IS_ERR(handle)) 577 return PTR_ERR(handle); 578 if (!handle) 579 return -EINVAL; 580 581 if (!clcnt && !resets && !p_state && !c_state) 582 return -EINVAL; 583 584 info = handle_to_ti_sci_info(handle); 585 dev = info->dev; 586 587 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_DEVICE_STATE, 588 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 589 sizeof(*req), sizeof(*resp)); 590 if (IS_ERR(xfer)) { 591 ret = PTR_ERR(xfer); 592 dev_err(dev, "Message alloc failed(%d)\n", ret); 593 return ret; 594 } 595 req = (struct ti_sci_msg_req_get_device_state *)xfer->xfer_buf; 596 req->id = id; 597 598 ret = ti_sci_do_xfer(info, xfer); 599 if (ret) { 600 dev_err(dev, "Mbox send fail %d\n", ret); 601 goto fail; 602 } 603 604 resp = (struct ti_sci_msg_resp_get_device_state *)xfer->xfer_buf; 605 if (!ti_sci_is_response_ack(resp)) { 606 ret = -ENODEV; 607 goto fail; 608 } 609 610 if (clcnt) 611 *clcnt = resp->context_loss_count; 612 if (resets) 613 *resets = resp->resets; 614 if (p_state) 615 *p_state = resp->programmed_state; 616 if (c_state) 617 *c_state = resp->current_state; 618 fail: 619 ti_sci_put_one_xfer(&info->minfo, xfer); 620 621 return ret; 622 } 623 624 /** 625 * ti_sci_cmd_get_device() - command to request for device managed by TISCI 626 * that can be shared with other hosts. 627 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 628 * @id: Device Identifier 629 * 630 * Request for the device - NOTE: the client MUST maintain integrity of 631 * usage count by balancing get_device with put_device. No refcounting is 632 * managed by driver for that purpose. 633 * 634 * Return: 0 if all went fine, else return appropriate error. 635 */ 636 static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id) 637 { 638 return ti_sci_set_device_state(handle, id, 0, 639 MSG_DEVICE_SW_STATE_ON); 640 } 641 642 /** 643 * ti_sci_cmd_get_device_exclusive() - command to request for device managed by 644 * TISCI that is exclusively owned by the 645 * requesting host. 646 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 647 * @id: Device Identifier 648 * 649 * Request for the device - NOTE: the client MUST maintain integrity of 650 * usage count by balancing get_device with put_device. No refcounting is 651 * managed by driver for that purpose. 652 * 653 * Return: 0 if all went fine, else return appropriate error. 654 */ 655 static int ti_sci_cmd_get_device_exclusive(const struct ti_sci_handle *handle, 656 u32 id) 657 { 658 return ti_sci_set_device_state(handle, id, 659 MSG_FLAG_DEVICE_EXCLUSIVE, 660 MSG_DEVICE_SW_STATE_ON); 661 } 662 663 /** 664 * ti_sci_cmd_idle_device() - Command to idle a device managed by TISCI 665 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 666 * @id: Device Identifier 667 * 668 * Request for the device - NOTE: the client MUST maintain integrity of 669 * usage count by balancing get_device with put_device. No refcounting is 670 * managed by driver for that purpose. 671 * 672 * Return: 0 if all went fine, else return appropriate error. 673 */ 674 static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id) 675 { 676 return ti_sci_set_device_state(handle, id, 0, 677 MSG_DEVICE_SW_STATE_RETENTION); 678 } 679 680 /** 681 * ti_sci_cmd_idle_device_exclusive() - Command to idle a device managed by 682 * TISCI that is exclusively owned by 683 * requesting host. 684 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 685 * @id: Device Identifier 686 * 687 * Request for the device - NOTE: the client MUST maintain integrity of 688 * usage count by balancing get_device with put_device. No refcounting is 689 * managed by driver for that purpose. 690 * 691 * Return: 0 if all went fine, else return appropriate error. 692 */ 693 static int ti_sci_cmd_idle_device_exclusive(const struct ti_sci_handle *handle, 694 u32 id) 695 { 696 return ti_sci_set_device_state(handle, id, 697 MSG_FLAG_DEVICE_EXCLUSIVE, 698 MSG_DEVICE_SW_STATE_RETENTION); 699 } 700 701 /** 702 * ti_sci_cmd_put_device() - command to release a device managed by TISCI 703 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 704 * @id: Device Identifier 705 * 706 * Request for the device - NOTE: the client MUST maintain integrity of 707 * usage count by balancing get_device with put_device. No refcounting is 708 * managed by driver for that purpose. 709 * 710 * Return: 0 if all went fine, else return appropriate error. 711 */ 712 static int ti_sci_cmd_put_device(const struct ti_sci_handle *handle, u32 id) 713 { 714 return ti_sci_set_device_state(handle, id, 715 0, MSG_DEVICE_SW_STATE_AUTO_OFF); 716 } 717 718 /** 719 * ti_sci_cmd_dev_is_valid() - Is the device valid 720 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 721 * @id: Device Identifier 722 * 723 * Return: 0 if all went fine and the device ID is valid, else return 724 * appropriate error. 725 */ 726 static int ti_sci_cmd_dev_is_valid(const struct ti_sci_handle *handle, u32 id) 727 { 728 u8 unused; 729 730 /* check the device state which will also tell us if the ID is valid */ 731 return ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &unused); 732 } 733 734 /** 735 * ti_sci_cmd_dev_get_clcnt() - Get context loss counter 736 * @handle: Pointer to TISCI handle 737 * @id: Device Identifier 738 * @count: Pointer to Context Loss counter to populate 739 * 740 * Return: 0 if all went fine, else return appropriate error. 741 */ 742 static int ti_sci_cmd_dev_get_clcnt(const struct ti_sci_handle *handle, u32 id, 743 u32 *count) 744 { 745 return ti_sci_get_device_state(handle, id, count, NULL, NULL, NULL); 746 } 747 748 /** 749 * ti_sci_cmd_dev_is_idle() - Check if the device is requested to be idle 750 * @handle: Pointer to TISCI handle 751 * @id: Device Identifier 752 * @r_state: true if requested to be idle 753 * 754 * Return: 0 if all went fine, else return appropriate error. 755 */ 756 static int ti_sci_cmd_dev_is_idle(const struct ti_sci_handle *handle, u32 id, 757 bool *r_state) 758 { 759 int ret; 760 u8 state; 761 762 if (!r_state) 763 return -EINVAL; 764 765 ret = ti_sci_get_device_state(handle, id, NULL, NULL, &state, NULL); 766 if (ret) 767 return ret; 768 769 *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION); 770 771 return 0; 772 } 773 774 /** 775 * ti_sci_cmd_dev_is_stop() - Check if the device is requested to be stopped 776 * @handle: Pointer to TISCI handle 777 * @id: Device Identifier 778 * @r_state: true if requested to be stopped 779 * @curr_state: true if currently stopped. 780 * 781 * Return: 0 if all went fine, else return appropriate error. 782 */ 783 static int ti_sci_cmd_dev_is_stop(const struct ti_sci_handle *handle, u32 id, 784 bool *r_state, bool *curr_state) 785 { 786 int ret; 787 u8 p_state, c_state; 788 789 if (!r_state && !curr_state) 790 return -EINVAL; 791 792 ret = 793 ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state); 794 if (ret) 795 return ret; 796 797 if (r_state) 798 *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF); 799 if (curr_state) 800 *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF); 801 802 return 0; 803 } 804 805 /** 806 * ti_sci_cmd_dev_is_on() - Check if the device is requested to be ON 807 * @handle: Pointer to TISCI handle 808 * @id: Device Identifier 809 * @r_state: true if requested to be ON 810 * @curr_state: true if currently ON and active 811 * 812 * Return: 0 if all went fine, else return appropriate error. 813 */ 814 static int ti_sci_cmd_dev_is_on(const struct ti_sci_handle *handle, u32 id, 815 bool *r_state, bool *curr_state) 816 { 817 int ret; 818 u8 p_state, c_state; 819 820 if (!r_state && !curr_state) 821 return -EINVAL; 822 823 ret = 824 ti_sci_get_device_state(handle, id, NULL, NULL, &p_state, &c_state); 825 if (ret) 826 return ret; 827 828 if (r_state) 829 *r_state = (p_state == MSG_DEVICE_SW_STATE_ON); 830 if (curr_state) 831 *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON); 832 833 return 0; 834 } 835 836 /** 837 * ti_sci_cmd_dev_is_trans() - Check if the device is currently transitioning 838 * @handle: Pointer to TISCI handle 839 * @id: Device Identifier 840 * @curr_state: true if currently transitioning. 841 * 842 * Return: 0 if all went fine, else return appropriate error. 843 */ 844 static int ti_sci_cmd_dev_is_trans(const struct ti_sci_handle *handle, u32 id, 845 bool *curr_state) 846 { 847 int ret; 848 u8 state; 849 850 if (!curr_state) 851 return -EINVAL; 852 853 ret = ti_sci_get_device_state(handle, id, NULL, NULL, NULL, &state); 854 if (ret) 855 return ret; 856 857 *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS); 858 859 return 0; 860 } 861 862 /** 863 * ti_sci_cmd_set_device_resets() - command to set resets for device managed 864 * by TISCI 865 * @handle: Pointer to TISCI handle as retrieved by *ti_sci_get_handle 866 * @id: Device Identifier 867 * @reset_state: Device specific reset bit field 868 * 869 * Return: 0 if all went fine, else return appropriate error. 870 */ 871 static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, 872 u32 id, u32 reset_state) 873 { 874 struct ti_sci_info *info; 875 struct ti_sci_msg_req_set_device_resets *req; 876 struct ti_sci_msg_hdr *resp; 877 struct ti_sci_xfer *xfer; 878 struct device *dev; 879 int ret = 0; 880 881 if (IS_ERR(handle)) 882 return PTR_ERR(handle); 883 if (!handle) 884 return -EINVAL; 885 886 info = handle_to_ti_sci_info(handle); 887 dev = info->dev; 888 889 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_DEVICE_RESETS, 890 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 891 sizeof(*req), sizeof(*resp)); 892 if (IS_ERR(xfer)) { 893 ret = PTR_ERR(xfer); 894 dev_err(dev, "Message alloc failed(%d)\n", ret); 895 return ret; 896 } 897 req = (struct ti_sci_msg_req_set_device_resets *)xfer->xfer_buf; 898 req->id = id; 899 req->resets = reset_state; 900 901 ret = ti_sci_do_xfer(info, xfer); 902 if (ret) { 903 dev_err(dev, "Mbox send fail %d\n", ret); 904 goto fail; 905 } 906 907 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 908 909 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 910 911 fail: 912 ti_sci_put_one_xfer(&info->minfo, xfer); 913 914 return ret; 915 } 916 917 /** 918 * ti_sci_cmd_get_device_resets() - Get reset state for device managed 919 * by TISCI 920 * @handle: Pointer to TISCI handle 921 * @id: Device Identifier 922 * @reset_state: Pointer to reset state to populate 923 * 924 * Return: 0 if all went fine, else return appropriate error. 925 */ 926 static int ti_sci_cmd_get_device_resets(const struct ti_sci_handle *handle, 927 u32 id, u32 *reset_state) 928 { 929 return ti_sci_get_device_state(handle, id, NULL, reset_state, NULL, 930 NULL); 931 } 932 933 /** 934 * ti_sci_set_clock_state() - Set clock state helper 935 * @handle: pointer to TI SCI handle 936 * @dev_id: Device identifier this request is for 937 * @clk_id: Clock identifier for the device for this request. 938 * Each device has it's own set of clock inputs. This indexes 939 * which clock input to modify. 940 * @flags: Header flags as needed 941 * @state: State to request for the clock. 942 * 943 * Return: 0 if all went well, else returns appropriate error value. 944 */ 945 static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, 946 u32 dev_id, u32 clk_id, 947 u32 flags, u8 state) 948 { 949 struct ti_sci_info *info; 950 struct ti_sci_msg_req_set_clock_state *req; 951 struct ti_sci_msg_hdr *resp; 952 struct ti_sci_xfer *xfer; 953 struct device *dev; 954 int ret = 0; 955 956 if (IS_ERR(handle)) 957 return PTR_ERR(handle); 958 if (!handle) 959 return -EINVAL; 960 961 info = handle_to_ti_sci_info(handle); 962 dev = info->dev; 963 964 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_STATE, 965 flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 966 sizeof(*req), sizeof(*resp)); 967 if (IS_ERR(xfer)) { 968 ret = PTR_ERR(xfer); 969 dev_err(dev, "Message alloc failed(%d)\n", ret); 970 return ret; 971 } 972 req = (struct ti_sci_msg_req_set_clock_state *)xfer->xfer_buf; 973 req->dev_id = dev_id; 974 if (clk_id < 255) { 975 req->clk_id = clk_id; 976 } else { 977 req->clk_id = 255; 978 req->clk_id_32 = clk_id; 979 } 980 req->request_state = state; 981 982 ret = ti_sci_do_xfer(info, xfer); 983 if (ret) { 984 dev_err(dev, "Mbox send fail %d\n", ret); 985 goto fail; 986 } 987 988 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 989 990 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 991 992 fail: 993 ti_sci_put_one_xfer(&info->minfo, xfer); 994 995 return ret; 996 } 997 998 /** 999 * ti_sci_cmd_get_clock_state() - Get clock state helper 1000 * @handle: pointer to TI SCI handle 1001 * @dev_id: Device identifier this request is for 1002 * @clk_id: Clock identifier for the device for this request. 1003 * Each device has it's own set of clock inputs. This indexes 1004 * which clock input to modify. 1005 * @programmed_state: State requested for clock to move to 1006 * @current_state: State that the clock is currently in 1007 * 1008 * Return: 0 if all went well, else returns appropriate error value. 1009 */ 1010 static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, 1011 u32 dev_id, u32 clk_id, 1012 u8 *programmed_state, u8 *current_state) 1013 { 1014 struct ti_sci_info *info; 1015 struct ti_sci_msg_req_get_clock_state *req; 1016 struct ti_sci_msg_resp_get_clock_state *resp; 1017 struct ti_sci_xfer *xfer; 1018 struct device *dev; 1019 int ret = 0; 1020 1021 if (IS_ERR(handle)) 1022 return PTR_ERR(handle); 1023 if (!handle) 1024 return -EINVAL; 1025 1026 if (!programmed_state && !current_state) 1027 return -EINVAL; 1028 1029 info = handle_to_ti_sci_info(handle); 1030 dev = info->dev; 1031 1032 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_STATE, 1033 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1034 sizeof(*req), sizeof(*resp)); 1035 if (IS_ERR(xfer)) { 1036 ret = PTR_ERR(xfer); 1037 dev_err(dev, "Message alloc failed(%d)\n", ret); 1038 return ret; 1039 } 1040 req = (struct ti_sci_msg_req_get_clock_state *)xfer->xfer_buf; 1041 req->dev_id = dev_id; 1042 if (clk_id < 255) { 1043 req->clk_id = clk_id; 1044 } else { 1045 req->clk_id = 255; 1046 req->clk_id_32 = clk_id; 1047 } 1048 1049 ret = ti_sci_do_xfer(info, xfer); 1050 if (ret) { 1051 dev_err(dev, "Mbox send fail %d\n", ret); 1052 goto fail; 1053 } 1054 1055 resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->xfer_buf; 1056 1057 if (!ti_sci_is_response_ack(resp)) { 1058 ret = -ENODEV; 1059 goto fail; 1060 } 1061 1062 if (programmed_state) 1063 *programmed_state = resp->programmed_state; 1064 if (current_state) 1065 *current_state = resp->current_state; 1066 1067 fail: 1068 ti_sci_put_one_xfer(&info->minfo, xfer); 1069 1070 return ret; 1071 } 1072 1073 /** 1074 * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI 1075 * @handle: pointer to TI SCI handle 1076 * @dev_id: Device identifier this request is for 1077 * @clk_id: Clock identifier for the device for this request. 1078 * Each device has it's own set of clock inputs. This indexes 1079 * which clock input to modify. 1080 * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false' 1081 * @can_change_freq: 'true' if frequency change is desired, else 'false' 1082 * @enable_input_term: 'true' if input termination is desired, else 'false' 1083 * 1084 * Return: 0 if all went well, else returns appropriate error value. 1085 */ 1086 static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id, 1087 u32 clk_id, bool needs_ssc, 1088 bool can_change_freq, bool enable_input_term) 1089 { 1090 u32 flags = 0; 1091 1092 flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0; 1093 flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0; 1094 flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0; 1095 1096 return ti_sci_set_clock_state(handle, dev_id, clk_id, flags, 1097 MSG_CLOCK_SW_STATE_REQ); 1098 } 1099 1100 /** 1101 * ti_sci_cmd_idle_clock() - Idle a clock which is in our control 1102 * @handle: pointer to TI SCI handle 1103 * @dev_id: Device identifier this request is for 1104 * @clk_id: Clock identifier for the device for this request. 1105 * Each device has it's own set of clock inputs. This indexes 1106 * which clock input to modify. 1107 * 1108 * NOTE: This clock must have been requested by get_clock previously. 1109 * 1110 * Return: 0 if all went well, else returns appropriate error value. 1111 */ 1112 static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle, 1113 u32 dev_id, u32 clk_id) 1114 { 1115 return ti_sci_set_clock_state(handle, dev_id, clk_id, 1116 MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE, 1117 MSG_CLOCK_SW_STATE_UNREQ); 1118 } 1119 1120 /** 1121 * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI 1122 * @handle: pointer to TI SCI handle 1123 * @dev_id: Device identifier this request is for 1124 * @clk_id: Clock identifier for the device for this request. 1125 * Each device has it's own set of clock inputs. This indexes 1126 * which clock input to modify. 1127 * 1128 * NOTE: This clock must have been requested by get_clock previously. 1129 * 1130 * Return: 0 if all went well, else returns appropriate error value. 1131 */ 1132 static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle, 1133 u32 dev_id, u32 clk_id) 1134 { 1135 return ti_sci_set_clock_state(handle, dev_id, clk_id, 1136 MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE, 1137 MSG_CLOCK_SW_STATE_AUTO); 1138 } 1139 1140 /** 1141 * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed 1142 * @handle: pointer to TI SCI handle 1143 * @dev_id: Device identifier this request is for 1144 * @clk_id: Clock identifier for the device for this request. 1145 * Each device has it's own set of clock inputs. This indexes 1146 * which clock input to modify. 1147 * @req_state: state indicating if the clock is auto managed 1148 * 1149 * Return: 0 if all went well, else returns appropriate error value. 1150 */ 1151 static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle, 1152 u32 dev_id, u32 clk_id, bool *req_state) 1153 { 1154 u8 state = 0; 1155 int ret; 1156 1157 if (!req_state) 1158 return -EINVAL; 1159 1160 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL); 1161 if (ret) 1162 return ret; 1163 1164 *req_state = (state == MSG_CLOCK_SW_STATE_AUTO); 1165 return 0; 1166 } 1167 1168 /** 1169 * ti_sci_cmd_clk_is_on() - Is the clock ON 1170 * @handle: pointer to TI SCI handle 1171 * @dev_id: Device identifier this request is for 1172 * @clk_id: Clock identifier for the device for this request. 1173 * Each device has it's own set of clock inputs. This indexes 1174 * which clock input to modify. 1175 * @req_state: state indicating if the clock is managed by us and enabled 1176 * @curr_state: state indicating if the clock is ready for operation 1177 * 1178 * Return: 0 if all went well, else returns appropriate error value. 1179 */ 1180 static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id, 1181 u32 clk_id, bool *req_state, bool *curr_state) 1182 { 1183 u8 c_state = 0, r_state = 0; 1184 int ret; 1185 1186 if (!req_state && !curr_state) 1187 return -EINVAL; 1188 1189 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, 1190 &r_state, &c_state); 1191 if (ret) 1192 return ret; 1193 1194 if (req_state) 1195 *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ); 1196 if (curr_state) 1197 *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY); 1198 return 0; 1199 } 1200 1201 /** 1202 * ti_sci_cmd_clk_is_off() - Is the clock OFF 1203 * @handle: pointer to TI SCI handle 1204 * @dev_id: Device identifier this request is for 1205 * @clk_id: Clock identifier for the device for this request. 1206 * Each device has it's own set of clock inputs. This indexes 1207 * which clock input to modify. 1208 * @req_state: state indicating if the clock is managed by us and disabled 1209 * @curr_state: state indicating if the clock is NOT ready for operation 1210 * 1211 * Return: 0 if all went well, else returns appropriate error value. 1212 */ 1213 static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id, 1214 u32 clk_id, bool *req_state, bool *curr_state) 1215 { 1216 u8 c_state = 0, r_state = 0; 1217 int ret; 1218 1219 if (!req_state && !curr_state) 1220 return -EINVAL; 1221 1222 ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, 1223 &r_state, &c_state); 1224 if (ret) 1225 return ret; 1226 1227 if (req_state) 1228 *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ); 1229 if (curr_state) 1230 *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY); 1231 return 0; 1232 } 1233 1234 /** 1235 * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock 1236 * @handle: pointer to TI SCI handle 1237 * @dev_id: Device identifier this request is for 1238 * @clk_id: Clock identifier for the device for this request. 1239 * Each device has it's own set of clock inputs. This indexes 1240 * which clock input to modify. 1241 * @parent_id: Parent clock identifier to set 1242 * 1243 * Return: 0 if all went well, else returns appropriate error value. 1244 */ 1245 static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, 1246 u32 dev_id, u32 clk_id, u32 parent_id) 1247 { 1248 struct ti_sci_info *info; 1249 struct ti_sci_msg_req_set_clock_parent *req; 1250 struct ti_sci_msg_hdr *resp; 1251 struct ti_sci_xfer *xfer; 1252 struct device *dev; 1253 int ret = 0; 1254 1255 if (IS_ERR(handle)) 1256 return PTR_ERR(handle); 1257 if (!handle) 1258 return -EINVAL; 1259 1260 info = handle_to_ti_sci_info(handle); 1261 dev = info->dev; 1262 1263 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_PARENT, 1264 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1265 sizeof(*req), sizeof(*resp)); 1266 if (IS_ERR(xfer)) { 1267 ret = PTR_ERR(xfer); 1268 dev_err(dev, "Message alloc failed(%d)\n", ret); 1269 return ret; 1270 } 1271 req = (struct ti_sci_msg_req_set_clock_parent *)xfer->xfer_buf; 1272 req->dev_id = dev_id; 1273 if (clk_id < 255) { 1274 req->clk_id = clk_id; 1275 } else { 1276 req->clk_id = 255; 1277 req->clk_id_32 = clk_id; 1278 } 1279 if (parent_id < 255) { 1280 req->parent_id = parent_id; 1281 } else { 1282 req->parent_id = 255; 1283 req->parent_id_32 = parent_id; 1284 } 1285 1286 ret = ti_sci_do_xfer(info, xfer); 1287 if (ret) { 1288 dev_err(dev, "Mbox send fail %d\n", ret); 1289 goto fail; 1290 } 1291 1292 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 1293 1294 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 1295 1296 fail: 1297 ti_sci_put_one_xfer(&info->minfo, xfer); 1298 1299 return ret; 1300 } 1301 1302 /** 1303 * ti_sci_cmd_clk_get_parent() - Get current parent clock source 1304 * @handle: pointer to TI SCI handle 1305 * @dev_id: Device identifier this request is for 1306 * @clk_id: Clock identifier for the device for this request. 1307 * Each device has it's own set of clock inputs. This indexes 1308 * which clock input to modify. 1309 * @parent_id: Current clock parent 1310 * 1311 * Return: 0 if all went well, else returns appropriate error value. 1312 */ 1313 static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, 1314 u32 dev_id, u32 clk_id, u32 *parent_id) 1315 { 1316 struct ti_sci_info *info; 1317 struct ti_sci_msg_req_get_clock_parent *req; 1318 struct ti_sci_msg_resp_get_clock_parent *resp; 1319 struct ti_sci_xfer *xfer; 1320 struct device *dev; 1321 int ret = 0; 1322 1323 if (IS_ERR(handle)) 1324 return PTR_ERR(handle); 1325 if (!handle || !parent_id) 1326 return -EINVAL; 1327 1328 info = handle_to_ti_sci_info(handle); 1329 dev = info->dev; 1330 1331 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_PARENT, 1332 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1333 sizeof(*req), sizeof(*resp)); 1334 if (IS_ERR(xfer)) { 1335 ret = PTR_ERR(xfer); 1336 dev_err(dev, "Message alloc failed(%d)\n", ret); 1337 return ret; 1338 } 1339 req = (struct ti_sci_msg_req_get_clock_parent *)xfer->xfer_buf; 1340 req->dev_id = dev_id; 1341 if (clk_id < 255) { 1342 req->clk_id = clk_id; 1343 } else { 1344 req->clk_id = 255; 1345 req->clk_id_32 = clk_id; 1346 } 1347 1348 ret = ti_sci_do_xfer(info, xfer); 1349 if (ret) { 1350 dev_err(dev, "Mbox send fail %d\n", ret); 1351 goto fail; 1352 } 1353 1354 resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->xfer_buf; 1355 1356 if (!ti_sci_is_response_ack(resp)) { 1357 ret = -ENODEV; 1358 } else { 1359 if (resp->parent_id < 255) 1360 *parent_id = resp->parent_id; 1361 else 1362 *parent_id = resp->parent_id_32; 1363 } 1364 1365 fail: 1366 ti_sci_put_one_xfer(&info->minfo, xfer); 1367 1368 return ret; 1369 } 1370 1371 /** 1372 * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source 1373 * @handle: pointer to TI SCI handle 1374 * @dev_id: Device identifier this request is for 1375 * @clk_id: Clock identifier for the device for this request. 1376 * Each device has it's own set of clock inputs. This indexes 1377 * which clock input to modify. 1378 * @num_parents: Returns he number of parents to the current clock. 1379 * 1380 * Return: 0 if all went well, else returns appropriate error value. 1381 */ 1382 static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, 1383 u32 dev_id, u32 clk_id, 1384 u32 *num_parents) 1385 { 1386 struct ti_sci_info *info; 1387 struct ti_sci_msg_req_get_clock_num_parents *req; 1388 struct ti_sci_msg_resp_get_clock_num_parents *resp; 1389 struct ti_sci_xfer *xfer; 1390 struct device *dev; 1391 int ret = 0; 1392 1393 if (IS_ERR(handle)) 1394 return PTR_ERR(handle); 1395 if (!handle || !num_parents) 1396 return -EINVAL; 1397 1398 info = handle_to_ti_sci_info(handle); 1399 dev = info->dev; 1400 1401 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, 1402 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1403 sizeof(*req), sizeof(*resp)); 1404 if (IS_ERR(xfer)) { 1405 ret = PTR_ERR(xfer); 1406 dev_err(dev, "Message alloc failed(%d)\n", ret); 1407 return ret; 1408 } 1409 req = (struct ti_sci_msg_req_get_clock_num_parents *)xfer->xfer_buf; 1410 req->dev_id = dev_id; 1411 if (clk_id < 255) { 1412 req->clk_id = clk_id; 1413 } else { 1414 req->clk_id = 255; 1415 req->clk_id_32 = clk_id; 1416 } 1417 1418 ret = ti_sci_do_xfer(info, xfer); 1419 if (ret) { 1420 dev_err(dev, "Mbox send fail %d\n", ret); 1421 goto fail; 1422 } 1423 1424 resp = (struct ti_sci_msg_resp_get_clock_num_parents *)xfer->xfer_buf; 1425 1426 if (!ti_sci_is_response_ack(resp)) { 1427 ret = -ENODEV; 1428 } else { 1429 if (resp->num_parents < 255) 1430 *num_parents = resp->num_parents; 1431 else 1432 *num_parents = resp->num_parents_32; 1433 } 1434 1435 fail: 1436 ti_sci_put_one_xfer(&info->minfo, xfer); 1437 1438 return ret; 1439 } 1440 1441 /** 1442 * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency 1443 * @handle: pointer to TI SCI handle 1444 * @dev_id: Device identifier this request is for 1445 * @clk_id: Clock identifier for the device for this request. 1446 * Each device has it's own set of clock inputs. This indexes 1447 * which clock input to modify. 1448 * @min_freq: The minimum allowable frequency in Hz. This is the minimum 1449 * allowable programmed frequency and does not account for clock 1450 * tolerances and jitter. 1451 * @target_freq: The target clock frequency in Hz. A frequency will be 1452 * processed as close to this target frequency as possible. 1453 * @max_freq: The maximum allowable frequency in Hz. This is the maximum 1454 * allowable programmed frequency and does not account for clock 1455 * tolerances and jitter. 1456 * @match_freq: Frequency match in Hz response. 1457 * 1458 * Return: 0 if all went well, else returns appropriate error value. 1459 */ 1460 static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, 1461 u32 dev_id, u32 clk_id, u64 min_freq, 1462 u64 target_freq, u64 max_freq, 1463 u64 *match_freq) 1464 { 1465 struct ti_sci_info *info; 1466 struct ti_sci_msg_req_query_clock_freq *req; 1467 struct ti_sci_msg_resp_query_clock_freq *resp; 1468 struct ti_sci_xfer *xfer; 1469 struct device *dev; 1470 int ret = 0; 1471 1472 if (IS_ERR(handle)) 1473 return PTR_ERR(handle); 1474 if (!handle || !match_freq) 1475 return -EINVAL; 1476 1477 info = handle_to_ti_sci_info(handle); 1478 dev = info->dev; 1479 1480 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_QUERY_CLOCK_FREQ, 1481 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1482 sizeof(*req), sizeof(*resp)); 1483 if (IS_ERR(xfer)) { 1484 ret = PTR_ERR(xfer); 1485 dev_err(dev, "Message alloc failed(%d)\n", ret); 1486 return ret; 1487 } 1488 req = (struct ti_sci_msg_req_query_clock_freq *)xfer->xfer_buf; 1489 req->dev_id = dev_id; 1490 if (clk_id < 255) { 1491 req->clk_id = clk_id; 1492 } else { 1493 req->clk_id = 255; 1494 req->clk_id_32 = clk_id; 1495 } 1496 req->min_freq_hz = min_freq; 1497 req->target_freq_hz = target_freq; 1498 req->max_freq_hz = max_freq; 1499 1500 ret = ti_sci_do_xfer(info, xfer); 1501 if (ret) { 1502 dev_err(dev, "Mbox send fail %d\n", ret); 1503 goto fail; 1504 } 1505 1506 resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->xfer_buf; 1507 1508 if (!ti_sci_is_response_ack(resp)) 1509 ret = -ENODEV; 1510 else 1511 *match_freq = resp->freq_hz; 1512 1513 fail: 1514 ti_sci_put_one_xfer(&info->minfo, xfer); 1515 1516 return ret; 1517 } 1518 1519 /** 1520 * ti_sci_cmd_clk_set_freq() - Set a frequency for clock 1521 * @handle: pointer to TI SCI handle 1522 * @dev_id: Device identifier this request is for 1523 * @clk_id: Clock identifier for the device for this request. 1524 * Each device has it's own set of clock inputs. This indexes 1525 * which clock input to modify. 1526 * @min_freq: The minimum allowable frequency in Hz. This is the minimum 1527 * allowable programmed frequency and does not account for clock 1528 * tolerances and jitter. 1529 * @target_freq: The target clock frequency in Hz. A frequency will be 1530 * processed as close to this target frequency as possible. 1531 * @max_freq: The maximum allowable frequency in Hz. This is the maximum 1532 * allowable programmed frequency and does not account for clock 1533 * tolerances and jitter. 1534 * 1535 * Return: 0 if all went well, else returns appropriate error value. 1536 */ 1537 static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, 1538 u32 dev_id, u32 clk_id, u64 min_freq, 1539 u64 target_freq, u64 max_freq) 1540 { 1541 struct ti_sci_info *info; 1542 struct ti_sci_msg_req_set_clock_freq *req; 1543 struct ti_sci_msg_hdr *resp; 1544 struct ti_sci_xfer *xfer; 1545 struct device *dev; 1546 int ret = 0; 1547 1548 if (IS_ERR(handle)) 1549 return PTR_ERR(handle); 1550 if (!handle) 1551 return -EINVAL; 1552 1553 info = handle_to_ti_sci_info(handle); 1554 dev = info->dev; 1555 1556 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CLOCK_FREQ, 1557 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1558 sizeof(*req), sizeof(*resp)); 1559 if (IS_ERR(xfer)) { 1560 ret = PTR_ERR(xfer); 1561 dev_err(dev, "Message alloc failed(%d)\n", ret); 1562 return ret; 1563 } 1564 req = (struct ti_sci_msg_req_set_clock_freq *)xfer->xfer_buf; 1565 req->dev_id = dev_id; 1566 if (clk_id < 255) { 1567 req->clk_id = clk_id; 1568 } else { 1569 req->clk_id = 255; 1570 req->clk_id_32 = clk_id; 1571 } 1572 req->min_freq_hz = min_freq; 1573 req->target_freq_hz = target_freq; 1574 req->max_freq_hz = max_freq; 1575 1576 ret = ti_sci_do_xfer(info, xfer); 1577 if (ret) { 1578 dev_err(dev, "Mbox send fail %d\n", ret); 1579 goto fail; 1580 } 1581 1582 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 1583 1584 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 1585 1586 fail: 1587 ti_sci_put_one_xfer(&info->minfo, xfer); 1588 1589 return ret; 1590 } 1591 1592 /** 1593 * ti_sci_cmd_clk_get_freq() - Get current frequency 1594 * @handle: pointer to TI SCI handle 1595 * @dev_id: Device identifier this request is for 1596 * @clk_id: Clock identifier for the device for this request. 1597 * Each device has it's own set of clock inputs. This indexes 1598 * which clock input to modify. 1599 * @freq: Currently frequency in Hz 1600 * 1601 * Return: 0 if all went well, else returns appropriate error value. 1602 */ 1603 static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, 1604 u32 dev_id, u32 clk_id, u64 *freq) 1605 { 1606 struct ti_sci_info *info; 1607 struct ti_sci_msg_req_get_clock_freq *req; 1608 struct ti_sci_msg_resp_get_clock_freq *resp; 1609 struct ti_sci_xfer *xfer; 1610 struct device *dev; 1611 int ret = 0; 1612 1613 if (IS_ERR(handle)) 1614 return PTR_ERR(handle); 1615 if (!handle || !freq) 1616 return -EINVAL; 1617 1618 info = handle_to_ti_sci_info(handle); 1619 dev = info->dev; 1620 1621 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_CLOCK_FREQ, 1622 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1623 sizeof(*req), sizeof(*resp)); 1624 if (IS_ERR(xfer)) { 1625 ret = PTR_ERR(xfer); 1626 dev_err(dev, "Message alloc failed(%d)\n", ret); 1627 return ret; 1628 } 1629 req = (struct ti_sci_msg_req_get_clock_freq *)xfer->xfer_buf; 1630 req->dev_id = dev_id; 1631 if (clk_id < 255) { 1632 req->clk_id = clk_id; 1633 } else { 1634 req->clk_id = 255; 1635 req->clk_id_32 = clk_id; 1636 } 1637 1638 ret = ti_sci_do_xfer(info, xfer); 1639 if (ret) { 1640 dev_err(dev, "Mbox send fail %d\n", ret); 1641 goto fail; 1642 } 1643 1644 resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->xfer_buf; 1645 1646 if (!ti_sci_is_response_ack(resp)) 1647 ret = -ENODEV; 1648 else 1649 *freq = resp->freq_hz; 1650 1651 fail: 1652 ti_sci_put_one_xfer(&info->minfo, xfer); 1653 1654 return ret; 1655 } 1656 1657 static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) 1658 { 1659 struct ti_sci_info *info; 1660 struct ti_sci_msg_req_reboot *req; 1661 struct ti_sci_msg_hdr *resp; 1662 struct ti_sci_xfer *xfer; 1663 struct device *dev; 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 dev = info->dev; 1673 1674 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SYS_RESET, 1675 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1676 sizeof(*req), sizeof(*resp)); 1677 if (IS_ERR(xfer)) { 1678 ret = PTR_ERR(xfer); 1679 dev_err(dev, "Message alloc failed(%d)\n", ret); 1680 return ret; 1681 } 1682 req = (struct ti_sci_msg_req_reboot *)xfer->xfer_buf; 1683 1684 ret = ti_sci_do_xfer(info, xfer); 1685 if (ret) { 1686 dev_err(dev, "Mbox send fail %d\n", ret); 1687 goto fail; 1688 } 1689 1690 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 1691 1692 if (!ti_sci_is_response_ack(resp)) 1693 ret = -ENODEV; 1694 else 1695 ret = 0; 1696 1697 fail: 1698 ti_sci_put_one_xfer(&info->minfo, xfer); 1699 1700 return ret; 1701 } 1702 1703 /** 1704 * ti_sci_get_resource_range - Helper to get a range of resources assigned 1705 * to a host. Resource is uniquely identified by 1706 * type and subtype. 1707 * @handle: Pointer to TISCI handle. 1708 * @dev_id: TISCI device ID. 1709 * @subtype: Resource assignment subtype that is being requested 1710 * from the given device. 1711 * @s_host: Host processor ID to which the resources are allocated 1712 * @desc: Pointer to ti_sci_resource_desc to be updated with the 1713 * resource range start index and number of resources 1714 * 1715 * Return: 0 if all went fine, else return appropriate error. 1716 */ 1717 static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, 1718 u32 dev_id, u8 subtype, u8 s_host, 1719 struct ti_sci_resource_desc *desc) 1720 { 1721 struct ti_sci_msg_resp_get_resource_range *resp; 1722 struct ti_sci_msg_req_get_resource_range *req; 1723 struct ti_sci_xfer *xfer; 1724 struct ti_sci_info *info; 1725 struct device *dev; 1726 int ret = 0; 1727 1728 if (IS_ERR(handle)) 1729 return PTR_ERR(handle); 1730 if (!handle || !desc) 1731 return -EINVAL; 1732 1733 info = handle_to_ti_sci_info(handle); 1734 dev = info->dev; 1735 1736 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE, 1737 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1738 sizeof(*req), sizeof(*resp)); 1739 if (IS_ERR(xfer)) { 1740 ret = PTR_ERR(xfer); 1741 dev_err(dev, "Message alloc failed(%d)\n", ret); 1742 return ret; 1743 } 1744 1745 req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf; 1746 req->secondary_host = s_host; 1747 req->type = dev_id & MSG_RM_RESOURCE_TYPE_MASK; 1748 req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK; 1749 1750 ret = ti_sci_do_xfer(info, xfer); 1751 if (ret) { 1752 dev_err(dev, "Mbox send fail %d\n", ret); 1753 goto fail; 1754 } 1755 1756 resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf; 1757 1758 if (!ti_sci_is_response_ack(resp)) { 1759 ret = -ENODEV; 1760 } else if (!resp->range_num && !resp->range_num_sec) { 1761 /* Neither of the two resource range is valid */ 1762 ret = -ENODEV; 1763 } else { 1764 desc->start = resp->range_start; 1765 desc->num = resp->range_num; 1766 desc->start_sec = resp->range_start_sec; 1767 desc->num_sec = resp->range_num_sec; 1768 } 1769 1770 fail: 1771 ti_sci_put_one_xfer(&info->minfo, xfer); 1772 1773 return ret; 1774 } 1775 1776 /** 1777 * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host 1778 * that is same as ti sci interface host. 1779 * @handle: Pointer to TISCI handle. 1780 * @dev_id: TISCI device ID. 1781 * @subtype: Resource assignment subtype that is being requested 1782 * from the given device. 1783 * @desc: Pointer to ti_sci_resource_desc to be updated with the 1784 * resource range start index and number of resources 1785 * 1786 * Return: 0 if all went fine, else return appropriate error. 1787 */ 1788 static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle, 1789 u32 dev_id, u8 subtype, 1790 struct ti_sci_resource_desc *desc) 1791 { 1792 return ti_sci_get_resource_range(handle, dev_id, subtype, 1793 TI_SCI_IRQ_SECONDARY_HOST_INVALID, 1794 desc); 1795 } 1796 1797 /** 1798 * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources 1799 * assigned to a specified host. 1800 * @handle: Pointer to TISCI handle. 1801 * @dev_id: TISCI device ID. 1802 * @subtype: Resource assignment subtype that is being requested 1803 * from the given device. 1804 * @s_host: Host processor ID to which the resources are allocated 1805 * @desc: Pointer to ti_sci_resource_desc to be updated with the 1806 * resource range start index and number of resources 1807 * 1808 * Return: 0 if all went fine, else return appropriate error. 1809 */ 1810 static 1811 int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle, 1812 u32 dev_id, u8 subtype, u8 s_host, 1813 struct ti_sci_resource_desc *desc) 1814 { 1815 return ti_sci_get_resource_range(handle, dev_id, subtype, s_host, desc); 1816 } 1817 1818 /** 1819 * ti_sci_manage_irq() - Helper api to configure/release the irq route between 1820 * the requested source and destination 1821 * @handle: Pointer to TISCI handle. 1822 * @valid_params: Bit fields defining the validity of certain params 1823 * @src_id: Device ID of the IRQ source 1824 * @src_index: IRQ source index within the source device 1825 * @dst_id: Device ID of the IRQ destination 1826 * @dst_host_irq: IRQ number of the destination device 1827 * @ia_id: Device ID of the IA, if the IRQ flows through this IA 1828 * @vint: Virtual interrupt to be used within the IA 1829 * @global_event: Global event number to be used for the requesting event 1830 * @vint_status_bit: Virtual interrupt status bit to be used for the event 1831 * @s_host: Secondary host ID to which the irq/event is being 1832 * requested for. 1833 * @type: Request type irq set or release. 1834 * 1835 * Return: 0 if all went fine, else return appropriate error. 1836 */ 1837 static int ti_sci_manage_irq(const struct ti_sci_handle *handle, 1838 u32 valid_params, u16 src_id, u16 src_index, 1839 u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint, 1840 u16 global_event, u8 vint_status_bit, u8 s_host, 1841 u16 type) 1842 { 1843 struct ti_sci_msg_req_manage_irq *req; 1844 struct ti_sci_msg_hdr *resp; 1845 struct ti_sci_xfer *xfer; 1846 struct ti_sci_info *info; 1847 struct device *dev; 1848 int ret = 0; 1849 1850 if (IS_ERR(handle)) 1851 return PTR_ERR(handle); 1852 if (!handle) 1853 return -EINVAL; 1854 1855 info = handle_to_ti_sci_info(handle); 1856 dev = info->dev; 1857 1858 xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 1859 sizeof(*req), sizeof(*resp)); 1860 if (IS_ERR(xfer)) { 1861 ret = PTR_ERR(xfer); 1862 dev_err(dev, "Message alloc failed(%d)\n", ret); 1863 return ret; 1864 } 1865 req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf; 1866 req->valid_params = valid_params; 1867 req->src_id = src_id; 1868 req->src_index = src_index; 1869 req->dst_id = dst_id; 1870 req->dst_host_irq = dst_host_irq; 1871 req->ia_id = ia_id; 1872 req->vint = vint; 1873 req->global_event = global_event; 1874 req->vint_status_bit = vint_status_bit; 1875 req->secondary_host = s_host; 1876 1877 ret = ti_sci_do_xfer(info, xfer); 1878 if (ret) { 1879 dev_err(dev, "Mbox send fail %d\n", ret); 1880 goto fail; 1881 } 1882 1883 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 1884 1885 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 1886 1887 fail: 1888 ti_sci_put_one_xfer(&info->minfo, xfer); 1889 1890 return ret; 1891 } 1892 1893 /** 1894 * ti_sci_set_irq() - Helper api to configure the irq route between the 1895 * requested source and destination 1896 * @handle: Pointer to TISCI handle. 1897 * @valid_params: Bit fields defining the validity of certain params 1898 * @src_id: Device ID of the IRQ source 1899 * @src_index: IRQ source index within the source device 1900 * @dst_id: Device ID of the IRQ destination 1901 * @dst_host_irq: IRQ number of the destination device 1902 * @ia_id: Device ID of the IA, if the IRQ flows through this IA 1903 * @vint: Virtual interrupt to be used within the IA 1904 * @global_event: Global event number to be used for the requesting event 1905 * @vint_status_bit: Virtual interrupt status bit to be used for the event 1906 * @s_host: Secondary host ID to which the irq/event is being 1907 * requested for. 1908 * 1909 * Return: 0 if all went fine, else return appropriate error. 1910 */ 1911 static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params, 1912 u16 src_id, u16 src_index, u16 dst_id, 1913 u16 dst_host_irq, u16 ia_id, u16 vint, 1914 u16 global_event, u8 vint_status_bit, u8 s_host) 1915 { 1916 pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n", 1917 __func__, valid_params, src_id, src_index, 1918 dst_id, dst_host_irq, ia_id, vint, global_event, 1919 vint_status_bit); 1920 1921 return ti_sci_manage_irq(handle, valid_params, src_id, src_index, 1922 dst_id, dst_host_irq, ia_id, vint, 1923 global_event, vint_status_bit, s_host, 1924 TI_SCI_MSG_SET_IRQ); 1925 } 1926 1927 /** 1928 * ti_sci_free_irq() - Helper api to free the irq route between the 1929 * requested source and destination 1930 * @handle: Pointer to TISCI handle. 1931 * @valid_params: Bit fields defining the validity of certain params 1932 * @src_id: Device ID of the IRQ source 1933 * @src_index: IRQ source index within the source device 1934 * @dst_id: Device ID of the IRQ destination 1935 * @dst_host_irq: IRQ number of the destination device 1936 * @ia_id: Device ID of the IA, if the IRQ flows through this IA 1937 * @vint: Virtual interrupt to be used within the IA 1938 * @global_event: Global event number to be used for the requesting event 1939 * @vint_status_bit: Virtual interrupt status bit to be used for the event 1940 * @s_host: Secondary host ID to which the irq/event is being 1941 * requested for. 1942 * 1943 * Return: 0 if all went fine, else return appropriate error. 1944 */ 1945 static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params, 1946 u16 src_id, u16 src_index, u16 dst_id, 1947 u16 dst_host_irq, u16 ia_id, u16 vint, 1948 u16 global_event, u8 vint_status_bit, u8 s_host) 1949 { 1950 pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n", 1951 __func__, valid_params, src_id, src_index, 1952 dst_id, dst_host_irq, ia_id, vint, global_event, 1953 vint_status_bit); 1954 1955 return ti_sci_manage_irq(handle, valid_params, src_id, src_index, 1956 dst_id, dst_host_irq, ia_id, vint, 1957 global_event, vint_status_bit, s_host, 1958 TI_SCI_MSG_FREE_IRQ); 1959 } 1960 1961 /** 1962 * ti_sci_cmd_set_irq() - Configure a host irq route between the requested 1963 * source and destination. 1964 * @handle: Pointer to TISCI handle. 1965 * @src_id: Device ID of the IRQ source 1966 * @src_index: IRQ source index within the source device 1967 * @dst_id: Device ID of the IRQ destination 1968 * @dst_host_irq: IRQ number of the destination device 1969 * 1970 * Return: 0 if all went fine, else return appropriate error. 1971 */ 1972 static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id, 1973 u16 src_index, u16 dst_id, u16 dst_host_irq) 1974 { 1975 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID; 1976 1977 return ti_sci_set_irq(handle, valid_params, src_id, src_index, dst_id, 1978 dst_host_irq, 0, 0, 0, 0, 0); 1979 } 1980 1981 /** 1982 * ti_sci_cmd_set_event_map() - Configure an event based irq route between the 1983 * requested source and Interrupt Aggregator. 1984 * @handle: Pointer to TISCI handle. 1985 * @src_id: Device ID of the IRQ source 1986 * @src_index: IRQ source index within the source device 1987 * @ia_id: Device ID of the IA, if the IRQ flows through this IA 1988 * @vint: Virtual interrupt to be used within the IA 1989 * @global_event: Global event number to be used for the requesting event 1990 * @vint_status_bit: Virtual interrupt status bit to be used for the event 1991 * 1992 * Return: 0 if all went fine, else return appropriate error. 1993 */ 1994 static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle, 1995 u16 src_id, u16 src_index, u16 ia_id, 1996 u16 vint, u16 global_event, 1997 u8 vint_status_bit) 1998 { 1999 u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID | 2000 MSG_FLAG_GLB_EVNT_VALID | 2001 MSG_FLAG_VINT_STS_BIT_VALID; 2002 2003 return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0, 2004 ia_id, vint, global_event, vint_status_bit, 0); 2005 } 2006 2007 /** 2008 * ti_sci_cmd_free_irq() - Free a host irq route between the between the 2009 * requested source and destination. 2010 * @handle: Pointer to TISCI handle. 2011 * @src_id: Device ID of the IRQ source 2012 * @src_index: IRQ source index within the source device 2013 * @dst_id: Device ID of the IRQ destination 2014 * @dst_host_irq: IRQ number of the destination device 2015 * 2016 * Return: 0 if all went fine, else return appropriate error. 2017 */ 2018 static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id, 2019 u16 src_index, u16 dst_id, u16 dst_host_irq) 2020 { 2021 u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID; 2022 2023 return ti_sci_free_irq(handle, valid_params, src_id, src_index, dst_id, 2024 dst_host_irq, 0, 0, 0, 0, 0); 2025 } 2026 2027 /** 2028 * ti_sci_cmd_free_event_map() - Free an event map between the requested source 2029 * and Interrupt Aggregator. 2030 * @handle: Pointer to TISCI handle. 2031 * @src_id: Device ID of the IRQ source 2032 * @src_index: IRQ source index within the source device 2033 * @ia_id: Device ID of the IA, if the IRQ flows through this IA 2034 * @vint: Virtual interrupt to be used within the IA 2035 * @global_event: Global event number to be used for the requesting event 2036 * @vint_status_bit: Virtual interrupt status bit to be used for the event 2037 * 2038 * Return: 0 if all went fine, else return appropriate error. 2039 */ 2040 static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle, 2041 u16 src_id, u16 src_index, u16 ia_id, 2042 u16 vint, u16 global_event, 2043 u8 vint_status_bit) 2044 { 2045 u32 valid_params = MSG_FLAG_IA_ID_VALID | 2046 MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID | 2047 MSG_FLAG_VINT_STS_BIT_VALID; 2048 2049 return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0, 2050 ia_id, vint, global_event, vint_status_bit, 0); 2051 } 2052 2053 /** 2054 * ti_sci_cmd_rm_ring_cfg() - Configure a NAVSS ring 2055 * @handle: Pointer to TI SCI handle. 2056 * @params: Pointer to ti_sci_msg_rm_ring_cfg ring config structure 2057 * 2058 * Return: 0 if all went well, else returns appropriate error value. 2059 * 2060 * See @ti_sci_msg_rm_ring_cfg and @ti_sci_msg_rm_ring_cfg_req for 2061 * more info. 2062 */ 2063 static int ti_sci_cmd_rm_ring_cfg(const struct ti_sci_handle *handle, 2064 const struct ti_sci_msg_rm_ring_cfg *params) 2065 { 2066 struct ti_sci_msg_rm_ring_cfg_req *req; 2067 struct ti_sci_msg_hdr *resp; 2068 struct ti_sci_xfer *xfer; 2069 struct ti_sci_info *info; 2070 struct device *dev; 2071 int ret = 0; 2072 2073 if (IS_ERR_OR_NULL(handle)) 2074 return -EINVAL; 2075 2076 info = handle_to_ti_sci_info(handle); 2077 dev = info->dev; 2078 2079 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_RING_CFG, 2080 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2081 sizeof(*req), sizeof(*resp)); 2082 if (IS_ERR(xfer)) { 2083 ret = PTR_ERR(xfer); 2084 dev_err(dev, "RM_RA:Message config failed(%d)\n", ret); 2085 return ret; 2086 } 2087 req = (struct ti_sci_msg_rm_ring_cfg_req *)xfer->xfer_buf; 2088 req->valid_params = params->valid_params; 2089 req->nav_id = params->nav_id; 2090 req->index = params->index; 2091 req->addr_lo = params->addr_lo; 2092 req->addr_hi = params->addr_hi; 2093 req->count = params->count; 2094 req->mode = params->mode; 2095 req->size = params->size; 2096 req->order_id = params->order_id; 2097 req->virtid = params->virtid; 2098 req->asel = params->asel; 2099 2100 ret = ti_sci_do_xfer(info, xfer); 2101 if (ret) { 2102 dev_err(dev, "RM_RA:Mbox config send fail %d\n", ret); 2103 goto fail; 2104 } 2105 2106 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 2107 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; 2108 2109 fail: 2110 ti_sci_put_one_xfer(&info->minfo, xfer); 2111 dev_dbg(dev, "RM_RA:config ring %u ret:%d\n", params->index, ret); 2112 return ret; 2113 } 2114 2115 /** 2116 * ti_sci_cmd_rm_psil_pair() - Pair PSI-L source to destination thread 2117 * @handle: Pointer to TI SCI handle. 2118 * @nav_id: Device ID of Navigator Subsystem which should be used for 2119 * pairing 2120 * @src_thread: Source PSI-L thread ID 2121 * @dst_thread: Destination PSI-L thread ID 2122 * 2123 * Return: 0 if all went well, else returns appropriate error value. 2124 */ 2125 static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle, 2126 u32 nav_id, u32 src_thread, u32 dst_thread) 2127 { 2128 struct ti_sci_msg_psil_pair *req; 2129 struct ti_sci_msg_hdr *resp; 2130 struct ti_sci_xfer *xfer; 2131 struct ti_sci_info *info; 2132 struct device *dev; 2133 int ret = 0; 2134 2135 if (IS_ERR(handle)) 2136 return PTR_ERR(handle); 2137 if (!handle) 2138 return -EINVAL; 2139 2140 info = handle_to_ti_sci_info(handle); 2141 dev = info->dev; 2142 2143 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_PAIR, 2144 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2145 sizeof(*req), sizeof(*resp)); 2146 if (IS_ERR(xfer)) { 2147 ret = PTR_ERR(xfer); 2148 dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret); 2149 return ret; 2150 } 2151 req = (struct ti_sci_msg_psil_pair *)xfer->xfer_buf; 2152 req->nav_id = nav_id; 2153 req->src_thread = src_thread; 2154 req->dst_thread = dst_thread; 2155 2156 ret = ti_sci_do_xfer(info, xfer); 2157 if (ret) { 2158 dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret); 2159 goto fail; 2160 } 2161 2162 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 2163 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; 2164 2165 fail: 2166 ti_sci_put_one_xfer(&info->minfo, xfer); 2167 2168 return ret; 2169 } 2170 2171 /** 2172 * ti_sci_cmd_rm_psil_unpair() - Unpair PSI-L source from destination thread 2173 * @handle: Pointer to TI SCI handle. 2174 * @nav_id: Device ID of Navigator Subsystem which should be used for 2175 * unpairing 2176 * @src_thread: Source PSI-L thread ID 2177 * @dst_thread: Destination PSI-L thread ID 2178 * 2179 * Return: 0 if all went well, else returns appropriate error value. 2180 */ 2181 static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle, 2182 u32 nav_id, u32 src_thread, u32 dst_thread) 2183 { 2184 struct ti_sci_msg_psil_unpair *req; 2185 struct ti_sci_msg_hdr *resp; 2186 struct ti_sci_xfer *xfer; 2187 struct ti_sci_info *info; 2188 struct device *dev; 2189 int ret = 0; 2190 2191 if (IS_ERR(handle)) 2192 return PTR_ERR(handle); 2193 if (!handle) 2194 return -EINVAL; 2195 2196 info = handle_to_ti_sci_info(handle); 2197 dev = info->dev; 2198 2199 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_RM_PSIL_UNPAIR, 2200 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2201 sizeof(*req), sizeof(*resp)); 2202 if (IS_ERR(xfer)) { 2203 ret = PTR_ERR(xfer); 2204 dev_err(dev, "RM_PSIL:Message reconfig failed(%d)\n", ret); 2205 return ret; 2206 } 2207 req = (struct ti_sci_msg_psil_unpair *)xfer->xfer_buf; 2208 req->nav_id = nav_id; 2209 req->src_thread = src_thread; 2210 req->dst_thread = dst_thread; 2211 2212 ret = ti_sci_do_xfer(info, xfer); 2213 if (ret) { 2214 dev_err(dev, "RM_PSIL:Mbox send fail %d\n", ret); 2215 goto fail; 2216 } 2217 2218 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 2219 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; 2220 2221 fail: 2222 ti_sci_put_one_xfer(&info->minfo, xfer); 2223 2224 return ret; 2225 } 2226 2227 /** 2228 * ti_sci_cmd_rm_udmap_tx_ch_cfg() - Configure a UDMAP TX channel 2229 * @handle: Pointer to TI SCI handle. 2230 * @params: Pointer to ti_sci_msg_rm_udmap_tx_ch_cfg TX channel config 2231 * structure 2232 * 2233 * Return: 0 if all went well, else returns appropriate error value. 2234 * 2235 * See @ti_sci_msg_rm_udmap_tx_ch_cfg and @ti_sci_msg_rm_udmap_tx_ch_cfg_req for 2236 * more info. 2237 */ 2238 static int ti_sci_cmd_rm_udmap_tx_ch_cfg(const struct ti_sci_handle *handle, 2239 const struct ti_sci_msg_rm_udmap_tx_ch_cfg *params) 2240 { 2241 struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *req; 2242 struct ti_sci_msg_hdr *resp; 2243 struct ti_sci_xfer *xfer; 2244 struct ti_sci_info *info; 2245 struct device *dev; 2246 int ret = 0; 2247 2248 if (IS_ERR_OR_NULL(handle)) 2249 return -EINVAL; 2250 2251 info = handle_to_ti_sci_info(handle); 2252 dev = info->dev; 2253 2254 xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_TX_CH_CFG, 2255 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2256 sizeof(*req), sizeof(*resp)); 2257 if (IS_ERR(xfer)) { 2258 ret = PTR_ERR(xfer); 2259 dev_err(dev, "Message TX_CH_CFG alloc failed(%d)\n", ret); 2260 return ret; 2261 } 2262 req = (struct ti_sci_msg_rm_udmap_tx_ch_cfg_req *)xfer->xfer_buf; 2263 req->valid_params = params->valid_params; 2264 req->nav_id = params->nav_id; 2265 req->index = params->index; 2266 req->tx_pause_on_err = params->tx_pause_on_err; 2267 req->tx_filt_einfo = params->tx_filt_einfo; 2268 req->tx_filt_pswords = params->tx_filt_pswords; 2269 req->tx_atype = params->tx_atype; 2270 req->tx_chan_type = params->tx_chan_type; 2271 req->tx_supr_tdpkt = params->tx_supr_tdpkt; 2272 req->tx_fetch_size = params->tx_fetch_size; 2273 req->tx_credit_count = params->tx_credit_count; 2274 req->txcq_qnum = params->txcq_qnum; 2275 req->tx_priority = params->tx_priority; 2276 req->tx_qos = params->tx_qos; 2277 req->tx_orderid = params->tx_orderid; 2278 req->fdepth = params->fdepth; 2279 req->tx_sched_priority = params->tx_sched_priority; 2280 req->tx_burst_size = params->tx_burst_size; 2281 req->tx_tdtype = params->tx_tdtype; 2282 req->extended_ch_type = params->extended_ch_type; 2283 2284 ret = ti_sci_do_xfer(info, xfer); 2285 if (ret) { 2286 dev_err(dev, "Mbox send TX_CH_CFG fail %d\n", ret); 2287 goto fail; 2288 } 2289 2290 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 2291 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; 2292 2293 fail: 2294 ti_sci_put_one_xfer(&info->minfo, xfer); 2295 dev_dbg(dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret); 2296 return ret; 2297 } 2298 2299 /** 2300 * ti_sci_cmd_rm_udmap_rx_ch_cfg() - Configure a UDMAP RX channel 2301 * @handle: Pointer to TI SCI handle. 2302 * @params: Pointer to ti_sci_msg_rm_udmap_rx_ch_cfg RX channel config 2303 * structure 2304 * 2305 * Return: 0 if all went well, else returns appropriate error value. 2306 * 2307 * See @ti_sci_msg_rm_udmap_rx_ch_cfg and @ti_sci_msg_rm_udmap_rx_ch_cfg_req for 2308 * more info. 2309 */ 2310 static int ti_sci_cmd_rm_udmap_rx_ch_cfg(const struct ti_sci_handle *handle, 2311 const struct ti_sci_msg_rm_udmap_rx_ch_cfg *params) 2312 { 2313 struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *req; 2314 struct ti_sci_msg_hdr *resp; 2315 struct ti_sci_xfer *xfer; 2316 struct ti_sci_info *info; 2317 struct device *dev; 2318 int ret = 0; 2319 2320 if (IS_ERR_OR_NULL(handle)) 2321 return -EINVAL; 2322 2323 info = handle_to_ti_sci_info(handle); 2324 dev = info->dev; 2325 2326 xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_RX_CH_CFG, 2327 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2328 sizeof(*req), sizeof(*resp)); 2329 if (IS_ERR(xfer)) { 2330 ret = PTR_ERR(xfer); 2331 dev_err(dev, "Message RX_CH_CFG alloc failed(%d)\n", ret); 2332 return ret; 2333 } 2334 req = (struct ti_sci_msg_rm_udmap_rx_ch_cfg_req *)xfer->xfer_buf; 2335 req->valid_params = params->valid_params; 2336 req->nav_id = params->nav_id; 2337 req->index = params->index; 2338 req->rx_fetch_size = params->rx_fetch_size; 2339 req->rxcq_qnum = params->rxcq_qnum; 2340 req->rx_priority = params->rx_priority; 2341 req->rx_qos = params->rx_qos; 2342 req->rx_orderid = params->rx_orderid; 2343 req->rx_sched_priority = params->rx_sched_priority; 2344 req->flowid_start = params->flowid_start; 2345 req->flowid_cnt = params->flowid_cnt; 2346 req->rx_pause_on_err = params->rx_pause_on_err; 2347 req->rx_atype = params->rx_atype; 2348 req->rx_chan_type = params->rx_chan_type; 2349 req->rx_ignore_short = params->rx_ignore_short; 2350 req->rx_ignore_long = params->rx_ignore_long; 2351 req->rx_burst_size = params->rx_burst_size; 2352 2353 ret = ti_sci_do_xfer(info, xfer); 2354 if (ret) { 2355 dev_err(dev, "Mbox send RX_CH_CFG fail %d\n", ret); 2356 goto fail; 2357 } 2358 2359 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 2360 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; 2361 2362 fail: 2363 ti_sci_put_one_xfer(&info->minfo, xfer); 2364 dev_dbg(dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret); 2365 return ret; 2366 } 2367 2368 /** 2369 * ti_sci_cmd_rm_udmap_rx_flow_cfg() - Configure UDMAP RX FLOW 2370 * @handle: Pointer to TI SCI handle. 2371 * @params: Pointer to ti_sci_msg_rm_udmap_flow_cfg RX FLOW config 2372 * structure 2373 * 2374 * Return: 0 if all went well, else returns appropriate error value. 2375 * 2376 * See @ti_sci_msg_rm_udmap_flow_cfg and @ti_sci_msg_rm_udmap_flow_cfg_req for 2377 * more info. 2378 */ 2379 static int ti_sci_cmd_rm_udmap_rx_flow_cfg(const struct ti_sci_handle *handle, 2380 const struct ti_sci_msg_rm_udmap_flow_cfg *params) 2381 { 2382 struct ti_sci_msg_rm_udmap_flow_cfg_req *req; 2383 struct ti_sci_msg_hdr *resp; 2384 struct ti_sci_xfer *xfer; 2385 struct ti_sci_info *info; 2386 struct device *dev; 2387 int ret = 0; 2388 2389 if (IS_ERR_OR_NULL(handle)) 2390 return -EINVAL; 2391 2392 info = handle_to_ti_sci_info(handle); 2393 dev = info->dev; 2394 2395 xfer = ti_sci_get_one_xfer(info, TISCI_MSG_RM_UDMAP_FLOW_CFG, 2396 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2397 sizeof(*req), sizeof(*resp)); 2398 if (IS_ERR(xfer)) { 2399 ret = PTR_ERR(xfer); 2400 dev_err(dev, "RX_FL_CFG: Message alloc failed(%d)\n", ret); 2401 return ret; 2402 } 2403 req = (struct ti_sci_msg_rm_udmap_flow_cfg_req *)xfer->xfer_buf; 2404 req->valid_params = params->valid_params; 2405 req->nav_id = params->nav_id; 2406 req->flow_index = params->flow_index; 2407 req->rx_einfo_present = params->rx_einfo_present; 2408 req->rx_psinfo_present = params->rx_psinfo_present; 2409 req->rx_error_handling = params->rx_error_handling; 2410 req->rx_desc_type = params->rx_desc_type; 2411 req->rx_sop_offset = params->rx_sop_offset; 2412 req->rx_dest_qnum = params->rx_dest_qnum; 2413 req->rx_src_tag_hi = params->rx_src_tag_hi; 2414 req->rx_src_tag_lo = params->rx_src_tag_lo; 2415 req->rx_dest_tag_hi = params->rx_dest_tag_hi; 2416 req->rx_dest_tag_lo = params->rx_dest_tag_lo; 2417 req->rx_src_tag_hi_sel = params->rx_src_tag_hi_sel; 2418 req->rx_src_tag_lo_sel = params->rx_src_tag_lo_sel; 2419 req->rx_dest_tag_hi_sel = params->rx_dest_tag_hi_sel; 2420 req->rx_dest_tag_lo_sel = params->rx_dest_tag_lo_sel; 2421 req->rx_fdq0_sz0_qnum = params->rx_fdq0_sz0_qnum; 2422 req->rx_fdq1_qnum = params->rx_fdq1_qnum; 2423 req->rx_fdq2_qnum = params->rx_fdq2_qnum; 2424 req->rx_fdq3_qnum = params->rx_fdq3_qnum; 2425 req->rx_ps_location = params->rx_ps_location; 2426 2427 ret = ti_sci_do_xfer(info, xfer); 2428 if (ret) { 2429 dev_err(dev, "RX_FL_CFG: Mbox send fail %d\n", ret); 2430 goto fail; 2431 } 2432 2433 resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; 2434 ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; 2435 2436 fail: 2437 ti_sci_put_one_xfer(&info->minfo, xfer); 2438 dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret); 2439 return ret; 2440 } 2441 2442 /** 2443 * ti_sci_cmd_proc_request() - Command to request a physical processor control 2444 * @handle: Pointer to TI SCI handle 2445 * @proc_id: Processor ID this request is for 2446 * 2447 * Return: 0 if all went well, else returns appropriate error value. 2448 */ 2449 static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, 2450 u8 proc_id) 2451 { 2452 struct ti_sci_msg_req_proc_request *req; 2453 struct ti_sci_msg_hdr *resp; 2454 struct ti_sci_info *info; 2455 struct ti_sci_xfer *xfer; 2456 struct device *dev; 2457 int ret = 0; 2458 2459 if (!handle) 2460 return -EINVAL; 2461 if (IS_ERR(handle)) 2462 return PTR_ERR(handle); 2463 2464 info = handle_to_ti_sci_info(handle); 2465 dev = info->dev; 2466 2467 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_REQUEST, 2468 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2469 sizeof(*req), sizeof(*resp)); 2470 if (IS_ERR(xfer)) { 2471 ret = PTR_ERR(xfer); 2472 dev_err(dev, "Message alloc failed(%d)\n", ret); 2473 return ret; 2474 } 2475 req = (struct ti_sci_msg_req_proc_request *)xfer->xfer_buf; 2476 req->processor_id = proc_id; 2477 2478 ret = ti_sci_do_xfer(info, xfer); 2479 if (ret) { 2480 dev_err(dev, "Mbox send fail %d\n", ret); 2481 goto fail; 2482 } 2483 2484 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 2485 2486 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 2487 2488 fail: 2489 ti_sci_put_one_xfer(&info->minfo, xfer); 2490 2491 return ret; 2492 } 2493 2494 /** 2495 * ti_sci_cmd_proc_release() - Command to release a physical processor control 2496 * @handle: Pointer to TI SCI handle 2497 * @proc_id: Processor ID this request is for 2498 * 2499 * Return: 0 if all went well, else returns appropriate error value. 2500 */ 2501 static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, 2502 u8 proc_id) 2503 { 2504 struct ti_sci_msg_req_proc_release *req; 2505 struct ti_sci_msg_hdr *resp; 2506 struct ti_sci_info *info; 2507 struct ti_sci_xfer *xfer; 2508 struct device *dev; 2509 int ret = 0; 2510 2511 if (!handle) 2512 return -EINVAL; 2513 if (IS_ERR(handle)) 2514 return PTR_ERR(handle); 2515 2516 info = handle_to_ti_sci_info(handle); 2517 dev = info->dev; 2518 2519 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_RELEASE, 2520 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2521 sizeof(*req), sizeof(*resp)); 2522 if (IS_ERR(xfer)) { 2523 ret = PTR_ERR(xfer); 2524 dev_err(dev, "Message alloc failed(%d)\n", ret); 2525 return ret; 2526 } 2527 req = (struct ti_sci_msg_req_proc_release *)xfer->xfer_buf; 2528 req->processor_id = proc_id; 2529 2530 ret = ti_sci_do_xfer(info, xfer); 2531 if (ret) { 2532 dev_err(dev, "Mbox send fail %d\n", ret); 2533 goto fail; 2534 } 2535 2536 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 2537 2538 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 2539 2540 fail: 2541 ti_sci_put_one_xfer(&info->minfo, xfer); 2542 2543 return ret; 2544 } 2545 2546 /** 2547 * ti_sci_cmd_proc_handover() - Command to handover a physical processor 2548 * control to a host in the processor's access 2549 * control list. 2550 * @handle: Pointer to TI SCI handle 2551 * @proc_id: Processor ID this request is for 2552 * @host_id: Host ID to get the control of the processor 2553 * 2554 * Return: 0 if all went well, else returns appropriate error value. 2555 */ 2556 static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, 2557 u8 proc_id, u8 host_id) 2558 { 2559 struct ti_sci_msg_req_proc_handover *req; 2560 struct ti_sci_msg_hdr *resp; 2561 struct ti_sci_info *info; 2562 struct ti_sci_xfer *xfer; 2563 struct device *dev; 2564 int ret = 0; 2565 2566 if (!handle) 2567 return -EINVAL; 2568 if (IS_ERR(handle)) 2569 return PTR_ERR(handle); 2570 2571 info = handle_to_ti_sci_info(handle); 2572 dev = info->dev; 2573 2574 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PROC_HANDOVER, 2575 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2576 sizeof(*req), sizeof(*resp)); 2577 if (IS_ERR(xfer)) { 2578 ret = PTR_ERR(xfer); 2579 dev_err(dev, "Message alloc failed(%d)\n", ret); 2580 return ret; 2581 } 2582 req = (struct ti_sci_msg_req_proc_handover *)xfer->xfer_buf; 2583 req->processor_id = proc_id; 2584 req->host_id = host_id; 2585 2586 ret = ti_sci_do_xfer(info, xfer); 2587 if (ret) { 2588 dev_err(dev, "Mbox send fail %d\n", ret); 2589 goto fail; 2590 } 2591 2592 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 2593 2594 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 2595 2596 fail: 2597 ti_sci_put_one_xfer(&info->minfo, xfer); 2598 2599 return ret; 2600 } 2601 2602 /** 2603 * ti_sci_cmd_proc_set_config() - Command to set the processor boot 2604 * configuration flags 2605 * @handle: Pointer to TI SCI handle 2606 * @proc_id: Processor ID this request is for 2607 * @bootvector: Processor Boot vector (start address) 2608 * @config_flags_set: Configuration flags to be set 2609 * @config_flags_clear: Configuration flags to be cleared. 2610 * 2611 * Return: 0 if all went well, else returns appropriate error value. 2612 */ 2613 static int ti_sci_cmd_proc_set_config(const struct ti_sci_handle *handle, 2614 u8 proc_id, u64 bootvector, 2615 u32 config_flags_set, 2616 u32 config_flags_clear) 2617 { 2618 struct ti_sci_msg_req_set_config *req; 2619 struct ti_sci_msg_hdr *resp; 2620 struct ti_sci_info *info; 2621 struct ti_sci_xfer *xfer; 2622 struct device *dev; 2623 int ret = 0; 2624 2625 if (!handle) 2626 return -EINVAL; 2627 if (IS_ERR(handle)) 2628 return PTR_ERR(handle); 2629 2630 info = handle_to_ti_sci_info(handle); 2631 dev = info->dev; 2632 2633 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CONFIG, 2634 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2635 sizeof(*req), sizeof(*resp)); 2636 if (IS_ERR(xfer)) { 2637 ret = PTR_ERR(xfer); 2638 dev_err(dev, "Message alloc failed(%d)\n", ret); 2639 return ret; 2640 } 2641 req = (struct ti_sci_msg_req_set_config *)xfer->xfer_buf; 2642 req->processor_id = proc_id; 2643 req->bootvector_low = bootvector & TI_SCI_ADDR_LOW_MASK; 2644 req->bootvector_high = (bootvector & TI_SCI_ADDR_HIGH_MASK) >> 2645 TI_SCI_ADDR_HIGH_SHIFT; 2646 req->config_flags_set = config_flags_set; 2647 req->config_flags_clear = config_flags_clear; 2648 2649 ret = ti_sci_do_xfer(info, xfer); 2650 if (ret) { 2651 dev_err(dev, "Mbox send fail %d\n", ret); 2652 goto fail; 2653 } 2654 2655 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 2656 2657 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 2658 2659 fail: 2660 ti_sci_put_one_xfer(&info->minfo, xfer); 2661 2662 return ret; 2663 } 2664 2665 /** 2666 * ti_sci_cmd_proc_set_control() - Command to set the processor boot 2667 * control flags 2668 * @handle: Pointer to TI SCI handle 2669 * @proc_id: Processor ID this request is for 2670 * @control_flags_set: Control flags to be set 2671 * @control_flags_clear: Control flags to be cleared 2672 * 2673 * Return: 0 if all went well, else returns appropriate error value. 2674 */ 2675 static int ti_sci_cmd_proc_set_control(const struct ti_sci_handle *handle, 2676 u8 proc_id, u32 control_flags_set, 2677 u32 control_flags_clear) 2678 { 2679 struct ti_sci_msg_req_set_ctrl *req; 2680 struct ti_sci_msg_hdr *resp; 2681 struct ti_sci_info *info; 2682 struct ti_sci_xfer *xfer; 2683 struct device *dev; 2684 int ret = 0; 2685 2686 if (!handle) 2687 return -EINVAL; 2688 if (IS_ERR(handle)) 2689 return PTR_ERR(handle); 2690 2691 info = handle_to_ti_sci_info(handle); 2692 dev = info->dev; 2693 2694 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_SET_CTRL, 2695 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2696 sizeof(*req), sizeof(*resp)); 2697 if (IS_ERR(xfer)) { 2698 ret = PTR_ERR(xfer); 2699 dev_err(dev, "Message alloc failed(%d)\n", ret); 2700 return ret; 2701 } 2702 req = (struct ti_sci_msg_req_set_ctrl *)xfer->xfer_buf; 2703 req->processor_id = proc_id; 2704 req->control_flags_set = control_flags_set; 2705 req->control_flags_clear = control_flags_clear; 2706 2707 ret = ti_sci_do_xfer(info, xfer); 2708 if (ret) { 2709 dev_err(dev, "Mbox send fail %d\n", ret); 2710 goto fail; 2711 } 2712 2713 resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; 2714 2715 ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; 2716 2717 fail: 2718 ti_sci_put_one_xfer(&info->minfo, xfer); 2719 2720 return ret; 2721 } 2722 2723 /** 2724 * ti_sci_cmd_proc_get_status() - Command to get the processor boot status 2725 * @handle: Pointer to TI SCI handle 2726 * @proc_id: Processor ID this request is for 2727 * @bv: Processor Boot vector (start address) 2728 * @cfg_flags: Processor specific configuration flags 2729 * @ctrl_flags: Processor specific control flags 2730 * @sts_flags: Processor specific status flags 2731 * 2732 * Return: 0 if all went well, else returns appropriate error value. 2733 */ 2734 static int ti_sci_cmd_proc_get_status(const struct ti_sci_handle *handle, 2735 u8 proc_id, u64 *bv, u32 *cfg_flags, 2736 u32 *ctrl_flags, u32 *sts_flags) 2737 { 2738 struct ti_sci_msg_resp_get_status *resp; 2739 struct ti_sci_msg_req_get_status *req; 2740 struct ti_sci_info *info; 2741 struct ti_sci_xfer *xfer; 2742 struct device *dev; 2743 int ret = 0; 2744 2745 if (!handle) 2746 return -EINVAL; 2747 if (IS_ERR(handle)) 2748 return PTR_ERR(handle); 2749 2750 info = handle_to_ti_sci_info(handle); 2751 dev = info->dev; 2752 2753 xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_STATUS, 2754 TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, 2755 sizeof(*req), sizeof(*resp)); 2756 if (IS_ERR(xfer)) { 2757 ret = PTR_ERR(xfer); 2758 dev_err(dev, "Message alloc failed(%d)\n", ret); 2759 return ret; 2760 } 2761 req = (struct ti_sci_msg_req_get_status *)xfer->xfer_buf; 2762 req->processor_id = proc_id; 2763 2764 ret = ti_sci_do_xfer(info, xfer); 2765 if (ret) { 2766 dev_err(dev, "Mbox send fail %d\n", ret); 2767 goto fail; 2768 } 2769 2770 resp = (struct ti_sci_msg_resp_get_status *)xfer->tx_message.buf; 2771 2772 if (!ti_sci_is_response_ack(resp)) { 2773 ret = -ENODEV; 2774 } else { 2775 *bv = (resp->bootvector_low & TI_SCI_ADDR_LOW_MASK) | 2776 (((u64)resp->bootvector_high << TI_SCI_ADDR_HIGH_SHIFT) & 2777 TI_SCI_ADDR_HIGH_MASK); 2778 *cfg_flags = resp->config_flags; 2779 *ctrl_flags = resp->control_flags; 2780 *sts_flags = resp->status_flags; 2781 } 2782 2783 fail: 2784 ti_sci_put_one_xfer(&info->minfo, xfer); 2785 2786 return ret; 2787 } 2788 2789 /* 2790 * ti_sci_setup_ops() - Setup the operations structures 2791 * @info: pointer to TISCI pointer 2792 */ 2793 static void ti_sci_setup_ops(struct ti_sci_info *info) 2794 { 2795 struct ti_sci_ops *ops = &info->handle.ops; 2796 struct ti_sci_core_ops *core_ops = &ops->core_ops; 2797 struct ti_sci_dev_ops *dops = &ops->dev_ops; 2798 struct ti_sci_clk_ops *cops = &ops->clk_ops; 2799 struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops; 2800 struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops; 2801 struct ti_sci_rm_ringacc_ops *rops = &ops->rm_ring_ops; 2802 struct ti_sci_rm_psil_ops *psilops = &ops->rm_psil_ops; 2803 struct ti_sci_rm_udmap_ops *udmap_ops = &ops->rm_udmap_ops; 2804 struct ti_sci_proc_ops *pops = &ops->proc_ops; 2805 2806 core_ops->reboot_device = ti_sci_cmd_core_reboot; 2807 2808 dops->get_device = ti_sci_cmd_get_device; 2809 dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive; 2810 dops->idle_device = ti_sci_cmd_idle_device; 2811 dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive; 2812 dops->put_device = ti_sci_cmd_put_device; 2813 2814 dops->is_valid = ti_sci_cmd_dev_is_valid; 2815 dops->get_context_loss_count = ti_sci_cmd_dev_get_clcnt; 2816 dops->is_idle = ti_sci_cmd_dev_is_idle; 2817 dops->is_stop = ti_sci_cmd_dev_is_stop; 2818 dops->is_on = ti_sci_cmd_dev_is_on; 2819 dops->is_transitioning = ti_sci_cmd_dev_is_trans; 2820 dops->set_device_resets = ti_sci_cmd_set_device_resets; 2821 dops->get_device_resets = ti_sci_cmd_get_device_resets; 2822 2823 cops->get_clock = ti_sci_cmd_get_clock; 2824 cops->idle_clock = ti_sci_cmd_idle_clock; 2825 cops->put_clock = ti_sci_cmd_put_clock; 2826 cops->is_auto = ti_sci_cmd_clk_is_auto; 2827 cops->is_on = ti_sci_cmd_clk_is_on; 2828 cops->is_off = ti_sci_cmd_clk_is_off; 2829 2830 cops->set_parent = ti_sci_cmd_clk_set_parent; 2831 cops->get_parent = ti_sci_cmd_clk_get_parent; 2832 cops->get_num_parents = ti_sci_cmd_clk_get_num_parents; 2833 2834 cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq; 2835 cops->set_freq = ti_sci_cmd_clk_set_freq; 2836 cops->get_freq = ti_sci_cmd_clk_get_freq; 2837 2838 rm_core_ops->get_range = ti_sci_cmd_get_resource_range; 2839 rm_core_ops->get_range_from_shost = 2840 ti_sci_cmd_get_resource_range_from_shost; 2841 2842 iops->set_irq = ti_sci_cmd_set_irq; 2843 iops->set_event_map = ti_sci_cmd_set_event_map; 2844 iops->free_irq = ti_sci_cmd_free_irq; 2845 iops->free_event_map = ti_sci_cmd_free_event_map; 2846 2847 rops->set_cfg = ti_sci_cmd_rm_ring_cfg; 2848 2849 psilops->pair = ti_sci_cmd_rm_psil_pair; 2850 psilops->unpair = ti_sci_cmd_rm_psil_unpair; 2851 2852 udmap_ops->tx_ch_cfg = ti_sci_cmd_rm_udmap_tx_ch_cfg; 2853 udmap_ops->rx_ch_cfg = ti_sci_cmd_rm_udmap_rx_ch_cfg; 2854 udmap_ops->rx_flow_cfg = ti_sci_cmd_rm_udmap_rx_flow_cfg; 2855 2856 pops->request = ti_sci_cmd_proc_request; 2857 pops->release = ti_sci_cmd_proc_release; 2858 pops->handover = ti_sci_cmd_proc_handover; 2859 pops->set_config = ti_sci_cmd_proc_set_config; 2860 pops->set_control = ti_sci_cmd_proc_set_control; 2861 pops->get_status = ti_sci_cmd_proc_get_status; 2862 } 2863 2864 /** 2865 * ti_sci_get_handle() - Get the TI SCI handle for a device 2866 * @dev: Pointer to device for which we want SCI handle 2867 * 2868 * NOTE: The function does not track individual clients of the framework 2869 * and is expected to be maintained by caller of TI SCI protocol library. 2870 * ti_sci_put_handle must be balanced with successful ti_sci_get_handle 2871 * Return: pointer to handle if successful, else: 2872 * -EPROBE_DEFER if the instance is not ready 2873 * -ENODEV if the required node handler is missing 2874 * -EINVAL if invalid conditions are encountered. 2875 */ 2876 const struct ti_sci_handle *ti_sci_get_handle(struct device *dev) 2877 { 2878 struct device_node *ti_sci_np; 2879 struct ti_sci_handle *handle = NULL; 2880 struct ti_sci_info *info; 2881 2882 if (!dev) { 2883 pr_err("I need a device pointer\n"); 2884 return ERR_PTR(-EINVAL); 2885 } 2886 ti_sci_np = of_get_parent(dev->of_node); 2887 if (!ti_sci_np) { 2888 dev_err(dev, "No OF information\n"); 2889 return ERR_PTR(-EINVAL); 2890 } 2891 2892 mutex_lock(&ti_sci_list_mutex); 2893 list_for_each_entry(info, &ti_sci_list, node) { 2894 if (ti_sci_np == info->dev->of_node) { 2895 handle = &info->handle; 2896 info->users++; 2897 break; 2898 } 2899 } 2900 mutex_unlock(&ti_sci_list_mutex); 2901 of_node_put(ti_sci_np); 2902 2903 if (!handle) 2904 return ERR_PTR(-EPROBE_DEFER); 2905 2906 return handle; 2907 } 2908 EXPORT_SYMBOL_GPL(ti_sci_get_handle); 2909 2910 /** 2911 * ti_sci_put_handle() - Release the handle acquired by ti_sci_get_handle 2912 * @handle: Handle acquired by ti_sci_get_handle 2913 * 2914 * NOTE: The function does not track individual clients of the framework 2915 * and is expected to be maintained by caller of TI SCI protocol library. 2916 * ti_sci_put_handle must be balanced with successful ti_sci_get_handle 2917 * 2918 * Return: 0 is successfully released 2919 * if an error pointer was passed, it returns the error value back, 2920 * if null was passed, it returns -EINVAL; 2921 */ 2922 int ti_sci_put_handle(const struct ti_sci_handle *handle) 2923 { 2924 struct ti_sci_info *info; 2925 2926 if (IS_ERR(handle)) 2927 return PTR_ERR(handle); 2928 if (!handle) 2929 return -EINVAL; 2930 2931 info = handle_to_ti_sci_info(handle); 2932 mutex_lock(&ti_sci_list_mutex); 2933 if (!WARN_ON(!info->users)) 2934 info->users--; 2935 mutex_unlock(&ti_sci_list_mutex); 2936 2937 return 0; 2938 } 2939 EXPORT_SYMBOL_GPL(ti_sci_put_handle); 2940 2941 static void devm_ti_sci_release(struct device *dev, void *res) 2942 { 2943 const struct ti_sci_handle **ptr = res; 2944 const struct ti_sci_handle *handle = *ptr; 2945 int ret; 2946 2947 ret = ti_sci_put_handle(handle); 2948 if (ret) 2949 dev_err(dev, "failed to put handle %d\n", ret); 2950 } 2951 2952 /** 2953 * devm_ti_sci_get_handle() - Managed get handle 2954 * @dev: device for which we want SCI handle for. 2955 * 2956 * NOTE: This releases the handle once the device resources are 2957 * no longer needed. MUST NOT BE released with ti_sci_put_handle. 2958 * The function does not track individual clients of the framework 2959 * and is expected to be maintained by caller of TI SCI protocol library. 2960 * 2961 * Return: 0 if all went fine, else corresponding error. 2962 */ 2963 const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev) 2964 { 2965 const struct ti_sci_handle **ptr; 2966 const struct ti_sci_handle *handle; 2967 2968 ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL); 2969 if (!ptr) 2970 return ERR_PTR(-ENOMEM); 2971 handle = ti_sci_get_handle(dev); 2972 2973 if (!IS_ERR(handle)) { 2974 *ptr = handle; 2975 devres_add(dev, ptr); 2976 } else { 2977 devres_free(ptr); 2978 } 2979 2980 return handle; 2981 } 2982 EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle); 2983 2984 /** 2985 * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle 2986 * @np: device node 2987 * @property: property name containing phandle on TISCI node 2988 * 2989 * NOTE: The function does not track individual clients of the framework 2990 * and is expected to be maintained by caller of TI SCI protocol library. 2991 * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle 2992 * Return: pointer to handle if successful, else: 2993 * -EPROBE_DEFER if the instance is not ready 2994 * -ENODEV if the required node handler is missing 2995 * -EINVAL if invalid conditions are encountered. 2996 */ 2997 const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np, 2998 const char *property) 2999 { 3000 struct ti_sci_handle *handle = NULL; 3001 struct device_node *ti_sci_np; 3002 struct ti_sci_info *info; 3003 3004 if (!np) { 3005 pr_err("I need a device pointer\n"); 3006 return ERR_PTR(-EINVAL); 3007 } 3008 3009 ti_sci_np = of_parse_phandle(np, property, 0); 3010 if (!ti_sci_np) 3011 return ERR_PTR(-ENODEV); 3012 3013 mutex_lock(&ti_sci_list_mutex); 3014 list_for_each_entry(info, &ti_sci_list, node) { 3015 if (ti_sci_np == info->dev->of_node) { 3016 handle = &info->handle; 3017 info->users++; 3018 break; 3019 } 3020 } 3021 mutex_unlock(&ti_sci_list_mutex); 3022 of_node_put(ti_sci_np); 3023 3024 if (!handle) 3025 return ERR_PTR(-EPROBE_DEFER); 3026 3027 return handle; 3028 } 3029 EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle); 3030 3031 /** 3032 * devm_ti_sci_get_by_phandle() - Managed get handle using phandle 3033 * @dev: Device pointer requesting TISCI handle 3034 * @property: property name containing phandle on TISCI node 3035 * 3036 * NOTE: This releases the handle once the device resources are 3037 * no longer needed. MUST NOT BE released with ti_sci_put_handle. 3038 * The function does not track individual clients of the framework 3039 * and is expected to be maintained by caller of TI SCI protocol library. 3040 * 3041 * Return: 0 if all went fine, else corresponding error. 3042 */ 3043 const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev, 3044 const char *property) 3045 { 3046 const struct ti_sci_handle *handle; 3047 const struct ti_sci_handle **ptr; 3048 3049 ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL); 3050 if (!ptr) 3051 return ERR_PTR(-ENOMEM); 3052 handle = ti_sci_get_by_phandle(dev_of_node(dev), property); 3053 3054 if (!IS_ERR(handle)) { 3055 *ptr = handle; 3056 devres_add(dev, ptr); 3057 } else { 3058 devres_free(ptr); 3059 } 3060 3061 return handle; 3062 } 3063 EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle); 3064 3065 /** 3066 * ti_sci_get_free_resource() - Get a free resource from TISCI resource. 3067 * @res: Pointer to the TISCI resource 3068 * 3069 * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL. 3070 */ 3071 u16 ti_sci_get_free_resource(struct ti_sci_resource *res) 3072 { 3073 unsigned long flags; 3074 u16 set, free_bit; 3075 3076 raw_spin_lock_irqsave(&res->lock, flags); 3077 for (set = 0; set < res->sets; set++) { 3078 struct ti_sci_resource_desc *desc = &res->desc[set]; 3079 int res_count = desc->num + desc->num_sec; 3080 3081 free_bit = find_first_zero_bit(desc->res_map, res_count); 3082 if (free_bit != res_count) { 3083 __set_bit(free_bit, desc->res_map); 3084 raw_spin_unlock_irqrestore(&res->lock, flags); 3085 3086 if (desc->num && free_bit < desc->num) 3087 return desc->start + free_bit; 3088 else 3089 return desc->start_sec + free_bit; 3090 } 3091 } 3092 raw_spin_unlock_irqrestore(&res->lock, flags); 3093 3094 return TI_SCI_RESOURCE_NULL; 3095 } 3096 EXPORT_SYMBOL_GPL(ti_sci_get_free_resource); 3097 3098 /** 3099 * ti_sci_release_resource() - Release a resource from TISCI resource. 3100 * @res: Pointer to the TISCI resource 3101 * @id: Resource id to be released. 3102 */ 3103 void ti_sci_release_resource(struct ti_sci_resource *res, u16 id) 3104 { 3105 unsigned long flags; 3106 u16 set; 3107 3108 raw_spin_lock_irqsave(&res->lock, flags); 3109 for (set = 0; set < res->sets; set++) { 3110 struct ti_sci_resource_desc *desc = &res->desc[set]; 3111 3112 if (desc->num && desc->start <= id && 3113 (desc->start + desc->num) > id) 3114 __clear_bit(id - desc->start, desc->res_map); 3115 else if (desc->num_sec && desc->start_sec <= id && 3116 (desc->start_sec + desc->num_sec) > id) 3117 __clear_bit(id - desc->start_sec, desc->res_map); 3118 } 3119 raw_spin_unlock_irqrestore(&res->lock, flags); 3120 } 3121 EXPORT_SYMBOL_GPL(ti_sci_release_resource); 3122 3123 /** 3124 * ti_sci_get_num_resources() - Get the number of resources in TISCI resource 3125 * @res: Pointer to the TISCI resource 3126 * 3127 * Return: Total number of available resources. 3128 */ 3129 u32 ti_sci_get_num_resources(struct ti_sci_resource *res) 3130 { 3131 u32 set, count = 0; 3132 3133 for (set = 0; set < res->sets; set++) 3134 count += res->desc[set].num + res->desc[set].num_sec; 3135 3136 return count; 3137 } 3138 EXPORT_SYMBOL_GPL(ti_sci_get_num_resources); 3139 3140 /** 3141 * devm_ti_sci_get_resource_sets() - Get a TISCI resources assigned to a device 3142 * @handle: TISCI handle 3143 * @dev: Device pointer to which the resource is assigned 3144 * @dev_id: TISCI device id to which the resource is assigned 3145 * @sub_types: Array of sub_types assigned corresponding to device 3146 * @sets: Number of sub_types 3147 * 3148 * Return: Pointer to ti_sci_resource if all went well else appropriate 3149 * error pointer. 3150 */ 3151 static struct ti_sci_resource * 3152 devm_ti_sci_get_resource_sets(const struct ti_sci_handle *handle, 3153 struct device *dev, u32 dev_id, u32 *sub_types, 3154 u32 sets) 3155 { 3156 struct ti_sci_resource *res; 3157 bool valid_set = false; 3158 int i, ret, res_count; 3159 3160 res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); 3161 if (!res) 3162 return ERR_PTR(-ENOMEM); 3163 3164 res->sets = sets; 3165 res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc), 3166 GFP_KERNEL); 3167 if (!res->desc) 3168 return ERR_PTR(-ENOMEM); 3169 3170 for (i = 0; i < res->sets; i++) { 3171 ret = handle->ops.rm_core_ops.get_range(handle, dev_id, 3172 sub_types[i], 3173 &res->desc[i]); 3174 if (ret) { 3175 dev_dbg(dev, "dev = %d subtype %d not allocated for this host\n", 3176 dev_id, sub_types[i]); 3177 memset(&res->desc[i], 0, sizeof(res->desc[i])); 3178 continue; 3179 } 3180 3181 dev_dbg(dev, "dev/sub_type: %d/%d, start/num: %d/%d | %d/%d\n", 3182 dev_id, sub_types[i], res->desc[i].start, 3183 res->desc[i].num, res->desc[i].start_sec, 3184 res->desc[i].num_sec); 3185 3186 valid_set = true; 3187 res_count = res->desc[i].num + res->desc[i].num_sec; 3188 res->desc[i].res_map = devm_bitmap_zalloc(dev, res_count, 3189 GFP_KERNEL); 3190 if (!res->desc[i].res_map) 3191 return ERR_PTR(-ENOMEM); 3192 } 3193 raw_spin_lock_init(&res->lock); 3194 3195 if (valid_set) 3196 return res; 3197 3198 return ERR_PTR(-EINVAL); 3199 } 3200 3201 /** 3202 * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device 3203 * @handle: TISCI handle 3204 * @dev: Device pointer to which the resource is assigned 3205 * @dev_id: TISCI device id to which the resource is assigned 3206 * @of_prop: property name by which the resource are represented 3207 * 3208 * Return: Pointer to ti_sci_resource if all went well else appropriate 3209 * error pointer. 3210 */ 3211 struct ti_sci_resource * 3212 devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle, 3213 struct device *dev, u32 dev_id, char *of_prop) 3214 { 3215 struct ti_sci_resource *res; 3216 u32 *sub_types; 3217 int sets; 3218 3219 sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop, 3220 sizeof(u32)); 3221 if (sets < 0) { 3222 dev_err(dev, "%s resource type ids not available\n", of_prop); 3223 return ERR_PTR(sets); 3224 } 3225 3226 sub_types = kcalloc(sets, sizeof(*sub_types), GFP_KERNEL); 3227 if (!sub_types) 3228 return ERR_PTR(-ENOMEM); 3229 3230 of_property_read_u32_array(dev_of_node(dev), of_prop, sub_types, sets); 3231 res = devm_ti_sci_get_resource_sets(handle, dev, dev_id, sub_types, 3232 sets); 3233 3234 kfree(sub_types); 3235 return res; 3236 } 3237 EXPORT_SYMBOL_GPL(devm_ti_sci_get_of_resource); 3238 3239 /** 3240 * devm_ti_sci_get_resource() - Get a resource range assigned to the device 3241 * @handle: TISCI handle 3242 * @dev: Device pointer to which the resource is assigned 3243 * @dev_id: TISCI device id to which the resource is assigned 3244 * @sub_type: TISCI resource subytpe representing the resource. 3245 * 3246 * Return: Pointer to ti_sci_resource if all went well else appropriate 3247 * error pointer. 3248 */ 3249 struct ti_sci_resource * 3250 devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev, 3251 u32 dev_id, u32 sub_type) 3252 { 3253 return devm_ti_sci_get_resource_sets(handle, dev, dev_id, &sub_type, 1); 3254 } 3255 EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource); 3256 3257 static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode, 3258 void *cmd) 3259 { 3260 struct ti_sci_info *info = reboot_to_ti_sci_info(nb); 3261 const struct ti_sci_handle *handle = &info->handle; 3262 3263 ti_sci_cmd_core_reboot(handle); 3264 3265 /* call fail OR pass, we should not be here in the first place */ 3266 return NOTIFY_BAD; 3267 } 3268 3269 /* Description for K2G */ 3270 static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = { 3271 .default_host_id = 2, 3272 /* Conservative duration */ 3273 .max_rx_timeout_ms = 1000, 3274 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */ 3275 .max_msgs = 20, 3276 .max_msg_size = 64, 3277 }; 3278 3279 /* Description for AM654 */ 3280 static const struct ti_sci_desc ti_sci_pmmc_am654_desc = { 3281 .default_host_id = 12, 3282 /* Conservative duration */ 3283 .max_rx_timeout_ms = 10000, 3284 /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */ 3285 .max_msgs = 20, 3286 .max_msg_size = 60, 3287 }; 3288 3289 static const struct of_device_id ti_sci_of_match[] = { 3290 {.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc}, 3291 {.compatible = "ti,am654-sci", .data = &ti_sci_pmmc_am654_desc}, 3292 { /* Sentinel */ }, 3293 }; 3294 MODULE_DEVICE_TABLE(of, ti_sci_of_match); 3295 3296 static int ti_sci_probe(struct platform_device *pdev) 3297 { 3298 struct device *dev = &pdev->dev; 3299 const struct ti_sci_desc *desc; 3300 struct ti_sci_xfer *xfer; 3301 struct ti_sci_info *info = NULL; 3302 struct ti_sci_xfers_info *minfo; 3303 struct mbox_client *cl; 3304 int ret = -EINVAL; 3305 int i; 3306 int reboot = 0; 3307 u32 h_id; 3308 3309 desc = device_get_match_data(dev); 3310 3311 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 3312 if (!info) 3313 return -ENOMEM; 3314 3315 info->dev = dev; 3316 info->desc = desc; 3317 ret = of_property_read_u32(dev->of_node, "ti,host-id", &h_id); 3318 /* if the property is not present in DT, use a default from desc */ 3319 if (ret < 0) { 3320 info->host_id = info->desc->default_host_id; 3321 } else { 3322 if (!h_id) { 3323 dev_warn(dev, "Host ID 0 is reserved for firmware\n"); 3324 info->host_id = info->desc->default_host_id; 3325 } else { 3326 info->host_id = h_id; 3327 } 3328 } 3329 3330 reboot = of_property_read_bool(dev->of_node, 3331 "ti,system-reboot-controller"); 3332 INIT_LIST_HEAD(&info->node); 3333 minfo = &info->minfo; 3334 3335 /* 3336 * Pre-allocate messages 3337 * NEVER allocate more than what we can indicate in hdr.seq 3338 * if we have data description bug, force a fix.. 3339 */ 3340 if (WARN_ON(desc->max_msgs >= 3341 1 << 8 * sizeof(((struct ti_sci_msg_hdr *)0)->seq))) 3342 return -EINVAL; 3343 3344 minfo->xfer_block = devm_kcalloc(dev, 3345 desc->max_msgs, 3346 sizeof(*minfo->xfer_block), 3347 GFP_KERNEL); 3348 if (!minfo->xfer_block) 3349 return -ENOMEM; 3350 3351 minfo->xfer_alloc_table = devm_bitmap_zalloc(dev, 3352 desc->max_msgs, 3353 GFP_KERNEL); 3354 if (!minfo->xfer_alloc_table) 3355 return -ENOMEM; 3356 3357 /* Pre-initialize the buffer pointer to pre-allocated buffers */ 3358 for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) { 3359 xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size, 3360 GFP_KERNEL); 3361 if (!xfer->xfer_buf) 3362 return -ENOMEM; 3363 3364 xfer->tx_message.buf = xfer->xfer_buf; 3365 init_completion(&xfer->done); 3366 } 3367 3368 ret = ti_sci_debugfs_create(pdev, info); 3369 if (ret) 3370 dev_warn(dev, "Failed to create debug file\n"); 3371 3372 platform_set_drvdata(pdev, info); 3373 3374 cl = &info->cl; 3375 cl->dev = dev; 3376 cl->tx_block = false; 3377 cl->rx_callback = ti_sci_rx_callback; 3378 cl->knows_txdone = true; 3379 3380 spin_lock_init(&minfo->xfer_lock); 3381 sema_init(&minfo->sem_xfer_count, desc->max_msgs); 3382 3383 info->chan_rx = mbox_request_channel_byname(cl, "rx"); 3384 if (IS_ERR(info->chan_rx)) { 3385 ret = PTR_ERR(info->chan_rx); 3386 goto out; 3387 } 3388 3389 info->chan_tx = mbox_request_channel_byname(cl, "tx"); 3390 if (IS_ERR(info->chan_tx)) { 3391 ret = PTR_ERR(info->chan_tx); 3392 goto out; 3393 } 3394 ret = ti_sci_cmd_get_revision(info); 3395 if (ret) { 3396 dev_err(dev, "Unable to communicate with TISCI(%d)\n", ret); 3397 goto out; 3398 } 3399 3400 ti_sci_setup_ops(info); 3401 3402 if (reboot) { 3403 info->nb.notifier_call = tisci_reboot_handler; 3404 info->nb.priority = 128; 3405 3406 ret = register_restart_handler(&info->nb); 3407 if (ret) { 3408 dev_err(dev, "reboot registration fail(%d)\n", ret); 3409 goto out; 3410 } 3411 } 3412 3413 dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n", 3414 info->handle.version.abi_major, info->handle.version.abi_minor, 3415 info->handle.version.firmware_revision, 3416 info->handle.version.firmware_description); 3417 3418 mutex_lock(&ti_sci_list_mutex); 3419 list_add_tail(&info->node, &ti_sci_list); 3420 mutex_unlock(&ti_sci_list_mutex); 3421 3422 return of_platform_populate(dev->of_node, NULL, NULL, dev); 3423 out: 3424 if (!IS_ERR(info->chan_tx)) 3425 mbox_free_channel(info->chan_tx); 3426 if (!IS_ERR(info->chan_rx)) 3427 mbox_free_channel(info->chan_rx); 3428 debugfs_remove(info->d); 3429 return ret; 3430 } 3431 3432 static struct platform_driver ti_sci_driver = { 3433 .probe = ti_sci_probe, 3434 .driver = { 3435 .name = "ti-sci", 3436 .of_match_table = of_match_ptr(ti_sci_of_match), 3437 .suppress_bind_attrs = true, 3438 }, 3439 }; 3440 module_platform_driver(ti_sci_driver); 3441 3442 MODULE_LICENSE("GPL v2"); 3443 MODULE_DESCRIPTION("TI System Control Interface(SCI) driver"); 3444 MODULE_AUTHOR("Nishanth Menon"); 3445 MODULE_ALIAS("platform:ti-sci"); 3446