1*32cd2512SLokesh Vutla // SPDX-License-Identifier: GPL-2.0+ 2*32cd2512SLokesh Vutla /* 3*32cd2512SLokesh Vutla * Texas Instruments System Control Interface Protocol Driver 4*32cd2512SLokesh Vutla * Based on drivers/firmware/ti_sci.c from Linux. 5*32cd2512SLokesh Vutla * 6*32cd2512SLokesh Vutla * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 7*32cd2512SLokesh Vutla * Lokesh Vutla <lokeshvutla@ti.com> 8*32cd2512SLokesh Vutla */ 9*32cd2512SLokesh Vutla 10*32cd2512SLokesh Vutla #include <common.h> 11*32cd2512SLokesh Vutla #include <dm.h> 12*32cd2512SLokesh Vutla #include <errno.h> 13*32cd2512SLokesh Vutla #include <mailbox.h> 14*32cd2512SLokesh Vutla #include <dm/device.h> 15*32cd2512SLokesh Vutla #include <linux/err.h> 16*32cd2512SLokesh Vutla #include <linux/soc/ti/k3-sec-proxy.h> 17*32cd2512SLokesh Vutla #include <linux/soc/ti/ti_sci_protocol.h> 18*32cd2512SLokesh Vutla 19*32cd2512SLokesh Vutla #include "ti_sci.h" 20*32cd2512SLokesh Vutla 21*32cd2512SLokesh Vutla /* List of all TI SCI devices active in system */ 22*32cd2512SLokesh Vutla static LIST_HEAD(ti_sci_list); 23*32cd2512SLokesh Vutla 24*32cd2512SLokesh Vutla /** 25*32cd2512SLokesh Vutla * struct ti_sci_xfer - Structure representing a message flow 26*32cd2512SLokesh Vutla * @tx_message: Transmit message 27*32cd2512SLokesh Vutla * @rx_len: Receive message length 28*32cd2512SLokesh Vutla */ 29*32cd2512SLokesh Vutla struct ti_sci_xfer { 30*32cd2512SLokesh Vutla struct k3_sec_proxy_msg tx_message; 31*32cd2512SLokesh Vutla u8 rx_len; 32*32cd2512SLokesh Vutla }; 33*32cd2512SLokesh Vutla 34*32cd2512SLokesh Vutla /** 35*32cd2512SLokesh Vutla * struct ti_sci_desc - Description of SoC integration 36*32cd2512SLokesh Vutla * @host_id: Host identifier representing the compute entity 37*32cd2512SLokesh Vutla * @max_rx_timeout_us: Timeout for communication with SoC (in Microseconds) 38*32cd2512SLokesh Vutla * @max_msg_size: Maximum size of data per message that can be handled. 39*32cd2512SLokesh Vutla */ 40*32cd2512SLokesh Vutla struct ti_sci_desc { 41*32cd2512SLokesh Vutla u8 host_id; 42*32cd2512SLokesh Vutla int max_rx_timeout_us; 43*32cd2512SLokesh Vutla int max_msg_size; 44*32cd2512SLokesh Vutla }; 45*32cd2512SLokesh Vutla 46*32cd2512SLokesh Vutla /** 47*32cd2512SLokesh Vutla * struct ti_sci_info - Structure representing a TI SCI instance 48*32cd2512SLokesh Vutla * @dev: Device pointer 49*32cd2512SLokesh Vutla * @desc: SoC description for this instance 50*32cd2512SLokesh Vutla * @handle: Instance of TI SCI handle to send to clients. 51*32cd2512SLokesh Vutla * @chan_tx: Transmit mailbox channel 52*32cd2512SLokesh Vutla * @chan_rx: Receive mailbox channel 53*32cd2512SLokesh Vutla * @xfer: xfer info 54*32cd2512SLokesh Vutla * @list: list head 55*32cd2512SLokesh Vutla * @is_secure: Determines if the communication is through secure threads. 56*32cd2512SLokesh Vutla * @host_id: Host identifier representing the compute entity 57*32cd2512SLokesh Vutla * @seq: Seq id used for verification for tx and rx message. 58*32cd2512SLokesh Vutla */ 59*32cd2512SLokesh Vutla struct ti_sci_info { 60*32cd2512SLokesh Vutla struct udevice *dev; 61*32cd2512SLokesh Vutla const struct ti_sci_desc *desc; 62*32cd2512SLokesh Vutla struct ti_sci_handle handle; 63*32cd2512SLokesh Vutla struct mbox_chan chan_tx; 64*32cd2512SLokesh Vutla struct mbox_chan chan_rx; 65*32cd2512SLokesh Vutla struct mbox_chan chan_notify; 66*32cd2512SLokesh Vutla struct ti_sci_xfer xfer; 67*32cd2512SLokesh Vutla struct list_head list; 68*32cd2512SLokesh Vutla bool is_secure; 69*32cd2512SLokesh Vutla u8 host_id; 70*32cd2512SLokesh Vutla u8 seq; 71*32cd2512SLokesh Vutla }; 72*32cd2512SLokesh Vutla 73*32cd2512SLokesh Vutla #define handle_to_ti_sci_info(h) container_of(h, struct ti_sci_info, handle) 74*32cd2512SLokesh Vutla 75*32cd2512SLokesh Vutla /** 76*32cd2512SLokesh Vutla * ti_sci_setup_one_xfer() - Setup one message type 77*32cd2512SLokesh Vutla * @info: Pointer to SCI entity information 78*32cd2512SLokesh Vutla * @msg_type: Message type 79*32cd2512SLokesh Vutla * @msg_flags: Flag to set for the message 80*32cd2512SLokesh Vutla * @buf: Buffer to be send to mailbox channel 81*32cd2512SLokesh Vutla * @tx_message_size: transmit message size 82*32cd2512SLokesh Vutla * @rx_message_size: receive message size 83*32cd2512SLokesh Vutla * 84*32cd2512SLokesh Vutla * Helper function which is used by various command functions that are 85*32cd2512SLokesh Vutla * exposed to clients of this driver for allocating a message traffic event. 86*32cd2512SLokesh Vutla * 87*32cd2512SLokesh Vutla * Return: Corresponding ti_sci_xfer pointer if all went fine, 88*32cd2512SLokesh Vutla * else appropriate error pointer. 89*32cd2512SLokesh Vutla */ 90*32cd2512SLokesh Vutla static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, 91*32cd2512SLokesh Vutla u16 msg_type, u32 msg_flags, 92*32cd2512SLokesh Vutla u32 *buf, 93*32cd2512SLokesh Vutla size_t tx_message_size, 94*32cd2512SLokesh Vutla size_t rx_message_size) 95*32cd2512SLokesh Vutla { 96*32cd2512SLokesh Vutla struct ti_sci_xfer *xfer = &info->xfer; 97*32cd2512SLokesh Vutla struct ti_sci_msg_hdr *hdr; 98*32cd2512SLokesh Vutla 99*32cd2512SLokesh Vutla /* Ensure we have sane transfer sizes */ 100*32cd2512SLokesh Vutla if (rx_message_size > info->desc->max_msg_size || 101*32cd2512SLokesh Vutla tx_message_size > info->desc->max_msg_size || 102*32cd2512SLokesh Vutla rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr)) 103*32cd2512SLokesh Vutla return ERR_PTR(-ERANGE); 104*32cd2512SLokesh Vutla 105*32cd2512SLokesh Vutla info->seq = ~info->seq; 106*32cd2512SLokesh Vutla xfer->tx_message.buf = buf; 107*32cd2512SLokesh Vutla xfer->tx_message.len = tx_message_size; 108*32cd2512SLokesh Vutla xfer->rx_len = (u8)rx_message_size; 109*32cd2512SLokesh Vutla 110*32cd2512SLokesh Vutla hdr = (struct ti_sci_msg_hdr *)buf; 111*32cd2512SLokesh Vutla hdr->seq = info->seq; 112*32cd2512SLokesh Vutla hdr->type = msg_type; 113*32cd2512SLokesh Vutla hdr->host = info->host_id; 114*32cd2512SLokesh Vutla hdr->flags = msg_flags; 115*32cd2512SLokesh Vutla 116*32cd2512SLokesh Vutla return xfer; 117*32cd2512SLokesh Vutla } 118*32cd2512SLokesh Vutla 119*32cd2512SLokesh Vutla /** 120*32cd2512SLokesh Vutla * ti_sci_get_response() - Receive response from mailbox channel 121*32cd2512SLokesh Vutla * @info: Pointer to SCI entity information 122*32cd2512SLokesh Vutla * @xfer: Transfer to initiate and wait for response 123*32cd2512SLokesh Vutla * @chan: Channel to receive the response 124*32cd2512SLokesh Vutla * 125*32cd2512SLokesh Vutla * Return: -ETIMEDOUT in case of no response, if transmit error, 126*32cd2512SLokesh Vutla * return corresponding error, else if all goes well, 127*32cd2512SLokesh Vutla * return 0. 128*32cd2512SLokesh Vutla */ 129*32cd2512SLokesh Vutla static inline int ti_sci_get_response(struct ti_sci_info *info, 130*32cd2512SLokesh Vutla struct ti_sci_xfer *xfer, 131*32cd2512SLokesh Vutla struct mbox_chan *chan) 132*32cd2512SLokesh Vutla { 133*32cd2512SLokesh Vutla struct k3_sec_proxy_msg *msg = &xfer->tx_message; 134*32cd2512SLokesh Vutla struct ti_sci_secure_msg_hdr *secure_hdr; 135*32cd2512SLokesh Vutla struct ti_sci_msg_hdr *hdr; 136*32cd2512SLokesh Vutla int ret; 137*32cd2512SLokesh Vutla 138*32cd2512SLokesh Vutla /* Receive the response */ 139*32cd2512SLokesh Vutla ret = mbox_recv(chan, msg, info->desc->max_rx_timeout_us); 140*32cd2512SLokesh Vutla if (ret) { 141*32cd2512SLokesh Vutla dev_err(info->dev, "%s: Message receive failed. ret = %d\n", 142*32cd2512SLokesh Vutla __func__, ret); 143*32cd2512SLokesh Vutla return ret; 144*32cd2512SLokesh Vutla } 145*32cd2512SLokesh Vutla 146*32cd2512SLokesh Vutla /* ToDo: Verify checksum */ 147*32cd2512SLokesh Vutla if (info->is_secure) { 148*32cd2512SLokesh Vutla secure_hdr = (struct ti_sci_secure_msg_hdr *)msg->buf; 149*32cd2512SLokesh Vutla msg->buf = (u32 *)((void *)msg->buf + sizeof(*secure_hdr)); 150*32cd2512SLokesh Vutla } 151*32cd2512SLokesh Vutla 152*32cd2512SLokesh Vutla /* msg is updated by mailbox driver */ 153*32cd2512SLokesh Vutla hdr = (struct ti_sci_msg_hdr *)msg->buf; 154*32cd2512SLokesh Vutla 155*32cd2512SLokesh Vutla /* Sanity check for message response */ 156*32cd2512SLokesh Vutla if (hdr->seq != info->seq) { 157*32cd2512SLokesh Vutla dev_dbg(info->dev, "%s: Message for %d is not expected\n", 158*32cd2512SLokesh Vutla __func__, hdr->seq); 159*32cd2512SLokesh Vutla return ret; 160*32cd2512SLokesh Vutla } 161*32cd2512SLokesh Vutla 162*32cd2512SLokesh Vutla if (msg->len > info->desc->max_msg_size) { 163*32cd2512SLokesh Vutla dev_err(info->dev, "%s: Unable to handle %zu xfer (max %d)\n", 164*32cd2512SLokesh Vutla __func__, msg->len, info->desc->max_msg_size); 165*32cd2512SLokesh Vutla return -EINVAL; 166*32cd2512SLokesh Vutla } 167*32cd2512SLokesh Vutla 168*32cd2512SLokesh Vutla if (msg->len < xfer->rx_len) { 169*32cd2512SLokesh Vutla dev_err(info->dev, "%s: Recv xfer %zu < expected %d length\n", 170*32cd2512SLokesh Vutla __func__, msg->len, xfer->rx_len); 171*32cd2512SLokesh Vutla } 172*32cd2512SLokesh Vutla 173*32cd2512SLokesh Vutla return ret; 174*32cd2512SLokesh Vutla } 175*32cd2512SLokesh Vutla 176*32cd2512SLokesh Vutla /** 177*32cd2512SLokesh Vutla * ti_sci_do_xfer() - Do one transfer 178*32cd2512SLokesh Vutla * @info: Pointer to SCI entity information 179*32cd2512SLokesh Vutla * @xfer: Transfer to initiate and wait for response 180*32cd2512SLokesh Vutla * 181*32cd2512SLokesh Vutla * Return: 0 if all went fine, else return appropriate error. 182*32cd2512SLokesh Vutla */ 183*32cd2512SLokesh Vutla static inline int ti_sci_do_xfer(struct ti_sci_info *info, 184*32cd2512SLokesh Vutla struct ti_sci_xfer *xfer) 185*32cd2512SLokesh Vutla { 186*32cd2512SLokesh Vutla struct k3_sec_proxy_msg *msg = &xfer->tx_message; 187*32cd2512SLokesh Vutla u8 secure_buf[info->desc->max_msg_size]; 188*32cd2512SLokesh Vutla struct ti_sci_secure_msg_hdr secure_hdr; 189*32cd2512SLokesh Vutla int ret; 190*32cd2512SLokesh Vutla 191*32cd2512SLokesh Vutla if (info->is_secure) { 192*32cd2512SLokesh Vutla /* ToDo: get checksum of the entire message */ 193*32cd2512SLokesh Vutla secure_hdr.checksum = 0; 194*32cd2512SLokesh Vutla secure_hdr.reserved = 0; 195*32cd2512SLokesh Vutla memcpy(&secure_buf[sizeof(secure_hdr)], xfer->tx_message.buf, 196*32cd2512SLokesh Vutla xfer->tx_message.len); 197*32cd2512SLokesh Vutla 198*32cd2512SLokesh Vutla xfer->tx_message.buf = (u32 *)secure_buf; 199*32cd2512SLokesh Vutla xfer->tx_message.len += sizeof(secure_hdr); 200*32cd2512SLokesh Vutla xfer->rx_len += sizeof(secure_hdr); 201*32cd2512SLokesh Vutla } 202*32cd2512SLokesh Vutla 203*32cd2512SLokesh Vutla /* Send the message */ 204*32cd2512SLokesh Vutla ret = mbox_send(&info->chan_tx, msg); 205*32cd2512SLokesh Vutla if (ret) { 206*32cd2512SLokesh Vutla dev_err(info->dev, "%s: Message sending failed. ret = %d\n", 207*32cd2512SLokesh Vutla __func__, ret); 208*32cd2512SLokesh Vutla return ret; 209*32cd2512SLokesh Vutla } 210*32cd2512SLokesh Vutla 211*32cd2512SLokesh Vutla return ti_sci_get_response(info, xfer, &info->chan_rx); 212*32cd2512SLokesh Vutla } 213*32cd2512SLokesh Vutla 214*32cd2512SLokesh Vutla /** 215*32cd2512SLokesh Vutla * ti_sci_cmd_get_revision() - command to get the revision of the SCI entity 216*32cd2512SLokesh Vutla * @handle: pointer to TI SCI handle 217*32cd2512SLokesh Vutla * 218*32cd2512SLokesh Vutla * Updates the SCI information in the internal data structure. 219*32cd2512SLokesh Vutla * 220*32cd2512SLokesh Vutla * Return: 0 if all went fine, else return appropriate error. 221*32cd2512SLokesh Vutla */ 222*32cd2512SLokesh Vutla static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) 223*32cd2512SLokesh Vutla { 224*32cd2512SLokesh Vutla struct ti_sci_msg_resp_version *rev_info; 225*32cd2512SLokesh Vutla struct ti_sci_version_info *ver; 226*32cd2512SLokesh Vutla struct ti_sci_msg_hdr hdr; 227*32cd2512SLokesh Vutla struct ti_sci_info *info; 228*32cd2512SLokesh Vutla struct ti_sci_xfer *xfer; 229*32cd2512SLokesh Vutla int ret; 230*32cd2512SLokesh Vutla 231*32cd2512SLokesh Vutla if (IS_ERR(handle)) 232*32cd2512SLokesh Vutla return PTR_ERR(handle); 233*32cd2512SLokesh Vutla if (!handle) 234*32cd2512SLokesh Vutla return -EINVAL; 235*32cd2512SLokesh Vutla 236*32cd2512SLokesh Vutla info = handle_to_ti_sci_info(handle); 237*32cd2512SLokesh Vutla 238*32cd2512SLokesh Vutla xfer = ti_sci_setup_one_xfer(info, TI_SCI_MSG_VERSION, 0x0, 239*32cd2512SLokesh Vutla (u32 *)&hdr, sizeof(struct ti_sci_msg_hdr), 240*32cd2512SLokesh Vutla sizeof(*rev_info)); 241*32cd2512SLokesh Vutla if (IS_ERR(xfer)) { 242*32cd2512SLokesh Vutla ret = PTR_ERR(xfer); 243*32cd2512SLokesh Vutla dev_err(info->dev, "Message alloc failed(%d)\n", ret); 244*32cd2512SLokesh Vutla return ret; 245*32cd2512SLokesh Vutla } 246*32cd2512SLokesh Vutla 247*32cd2512SLokesh Vutla ret = ti_sci_do_xfer(info, xfer); 248*32cd2512SLokesh Vutla if (ret) { 249*32cd2512SLokesh Vutla dev_err(info->dev, "Mbox communication fail %d\n", ret); 250*32cd2512SLokesh Vutla return ret; 251*32cd2512SLokesh Vutla } 252*32cd2512SLokesh Vutla 253*32cd2512SLokesh Vutla rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf; 254*32cd2512SLokesh Vutla 255*32cd2512SLokesh Vutla ver = &handle->version; 256*32cd2512SLokesh Vutla ver->abi_major = rev_info->abi_major; 257*32cd2512SLokesh Vutla ver->abi_minor = rev_info->abi_minor; 258*32cd2512SLokesh Vutla ver->firmware_revision = rev_info->firmware_revision; 259*32cd2512SLokesh Vutla strncpy(ver->firmware_description, rev_info->firmware_description, 260*32cd2512SLokesh Vutla sizeof(ver->firmware_description)); 261*32cd2512SLokesh Vutla 262*32cd2512SLokesh Vutla return 0; 263*32cd2512SLokesh Vutla } 264*32cd2512SLokesh Vutla 265*32cd2512SLokesh Vutla /** 266*32cd2512SLokesh Vutla * ti_sci_is_response_ack() - Generic ACK/NACK message checkup 267*32cd2512SLokesh Vutla * @r: pointer to response buffer 268*32cd2512SLokesh Vutla * 269*32cd2512SLokesh Vutla * Return: true if the response was an ACK, else returns false. 270*32cd2512SLokesh Vutla */ 271*32cd2512SLokesh Vutla static inline bool ti_sci_is_response_ack(void *r) 272*32cd2512SLokesh Vutla { 273*32cd2512SLokesh Vutla struct ti_sci_msg_hdr *hdr = r; 274*32cd2512SLokesh Vutla 275*32cd2512SLokesh Vutla return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; 276*32cd2512SLokesh Vutla } 277*32cd2512SLokesh Vutla 278*32cd2512SLokesh Vutla /** 279*32cd2512SLokesh Vutla * ti_sci_get_handle_from_sysfw() - Get the TI SCI handle of the SYSFW 280*32cd2512SLokesh Vutla * @dev: Pointer to the SYSFW device 281*32cd2512SLokesh Vutla * 282*32cd2512SLokesh Vutla * Return: pointer to handle if successful, else EINVAL if invalid conditions 283*32cd2512SLokesh Vutla * are encountered. 284*32cd2512SLokesh Vutla */ 285*32cd2512SLokesh Vutla const 286*32cd2512SLokesh Vutla struct ti_sci_handle *ti_sci_get_handle_from_sysfw(struct udevice *sci_dev) 287*32cd2512SLokesh Vutla { 288*32cd2512SLokesh Vutla if (!sci_dev) 289*32cd2512SLokesh Vutla return ERR_PTR(-EINVAL); 290*32cd2512SLokesh Vutla 291*32cd2512SLokesh Vutla struct ti_sci_info *info = dev_get_priv(sci_dev); 292*32cd2512SLokesh Vutla 293*32cd2512SLokesh Vutla if (!info) 294*32cd2512SLokesh Vutla return ERR_PTR(-EINVAL); 295*32cd2512SLokesh Vutla 296*32cd2512SLokesh Vutla struct ti_sci_handle *handle = &info->handle; 297*32cd2512SLokesh Vutla 298*32cd2512SLokesh Vutla if (!handle) 299*32cd2512SLokesh Vutla return ERR_PTR(-EINVAL); 300*32cd2512SLokesh Vutla 301*32cd2512SLokesh Vutla return handle; 302*32cd2512SLokesh Vutla } 303*32cd2512SLokesh Vutla 304*32cd2512SLokesh Vutla /** 305*32cd2512SLokesh Vutla * ti_sci_get_handle() - Get the TI SCI handle for a device 306*32cd2512SLokesh Vutla * @dev: Pointer to device for which we want SCI handle 307*32cd2512SLokesh Vutla * 308*32cd2512SLokesh Vutla * Return: pointer to handle if successful, else EINVAL if invalid conditions 309*32cd2512SLokesh Vutla * are encountered. 310*32cd2512SLokesh Vutla */ 311*32cd2512SLokesh Vutla const struct ti_sci_handle *ti_sci_get_handle(struct udevice *dev) 312*32cd2512SLokesh Vutla { 313*32cd2512SLokesh Vutla if (!dev) 314*32cd2512SLokesh Vutla return ERR_PTR(-EINVAL); 315*32cd2512SLokesh Vutla 316*32cd2512SLokesh Vutla struct udevice *sci_dev = dev_get_parent(dev); 317*32cd2512SLokesh Vutla 318*32cd2512SLokesh Vutla return ti_sci_get_handle_from_sysfw(sci_dev); 319*32cd2512SLokesh Vutla } 320*32cd2512SLokesh Vutla 321*32cd2512SLokesh Vutla /** 322*32cd2512SLokesh Vutla * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle 323*32cd2512SLokesh Vutla * @dev: device node 324*32cd2512SLokesh Vutla * @propname: property name containing phandle on TISCI node 325*32cd2512SLokesh Vutla * 326*32cd2512SLokesh Vutla * Return: pointer to handle if successful, else appropriate error value. 327*32cd2512SLokesh Vutla */ 328*32cd2512SLokesh Vutla const struct ti_sci_handle *ti_sci_get_by_phandle(struct udevice *dev, 329*32cd2512SLokesh Vutla const char *property) 330*32cd2512SLokesh Vutla { 331*32cd2512SLokesh Vutla struct ti_sci_info *entry, *info = NULL; 332*32cd2512SLokesh Vutla u32 phandle, err; 333*32cd2512SLokesh Vutla ofnode node; 334*32cd2512SLokesh Vutla 335*32cd2512SLokesh Vutla err = ofnode_read_u32(dev_ofnode(dev), property, &phandle); 336*32cd2512SLokesh Vutla if (err) 337*32cd2512SLokesh Vutla return ERR_PTR(err); 338*32cd2512SLokesh Vutla 339*32cd2512SLokesh Vutla node = ofnode_get_by_phandle(phandle); 340*32cd2512SLokesh Vutla if (!ofnode_valid(node)) 341*32cd2512SLokesh Vutla return ERR_PTR(-EINVAL); 342*32cd2512SLokesh Vutla 343*32cd2512SLokesh Vutla list_for_each_entry(entry, &ti_sci_list, list) 344*32cd2512SLokesh Vutla if (ofnode_equal(dev_ofnode(entry->dev), node)) { 345*32cd2512SLokesh Vutla info = entry; 346*32cd2512SLokesh Vutla break; 347*32cd2512SLokesh Vutla } 348*32cd2512SLokesh Vutla 349*32cd2512SLokesh Vutla if (!info) 350*32cd2512SLokesh Vutla return ERR_PTR(-ENODEV); 351*32cd2512SLokesh Vutla 352*32cd2512SLokesh Vutla return &info->handle; 353*32cd2512SLokesh Vutla } 354*32cd2512SLokesh Vutla 355*32cd2512SLokesh Vutla /** 356*32cd2512SLokesh Vutla * ti_sci_of_to_info() - generate private data from device tree 357*32cd2512SLokesh Vutla * @dev: corresponding system controller interface device 358*32cd2512SLokesh Vutla * @info: pointer to driver specific private data 359*32cd2512SLokesh Vutla * 360*32cd2512SLokesh Vutla * Return: 0 if all goes good, else appropriate error message. 361*32cd2512SLokesh Vutla */ 362*32cd2512SLokesh Vutla static int ti_sci_of_to_info(struct udevice *dev, struct ti_sci_info *info) 363*32cd2512SLokesh Vutla { 364*32cd2512SLokesh Vutla int ret; 365*32cd2512SLokesh Vutla 366*32cd2512SLokesh Vutla ret = mbox_get_by_name(dev, "tx", &info->chan_tx); 367*32cd2512SLokesh Vutla if (ret) { 368*32cd2512SLokesh Vutla dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n", 369*32cd2512SLokesh Vutla __func__, ret); 370*32cd2512SLokesh Vutla return ret; 371*32cd2512SLokesh Vutla } 372*32cd2512SLokesh Vutla 373*32cd2512SLokesh Vutla ret = mbox_get_by_name(dev, "rx", &info->chan_rx); 374*32cd2512SLokesh Vutla if (ret) { 375*32cd2512SLokesh Vutla dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n", 376*32cd2512SLokesh Vutla __func__, ret); 377*32cd2512SLokesh Vutla return ret; 378*32cd2512SLokesh Vutla } 379*32cd2512SLokesh Vutla 380*32cd2512SLokesh Vutla /* Notify channel is optional. Enable only if populated */ 381*32cd2512SLokesh Vutla ret = mbox_get_by_name(dev, "notify", &info->chan_notify); 382*32cd2512SLokesh Vutla if (ret) { 383*32cd2512SLokesh Vutla dev_dbg(dev, "%s: Acquiring notify channel failed. ret = %d\n", 384*32cd2512SLokesh Vutla __func__, ret); 385*32cd2512SLokesh Vutla } 386*32cd2512SLokesh Vutla 387*32cd2512SLokesh Vutla info->host_id = dev_read_u32_default(dev, "ti,host-id", 388*32cd2512SLokesh Vutla info->desc->host_id); 389*32cd2512SLokesh Vutla 390*32cd2512SLokesh Vutla info->is_secure = dev_read_bool(dev, "ti,secure-host"); 391*32cd2512SLokesh Vutla 392*32cd2512SLokesh Vutla return 0; 393*32cd2512SLokesh Vutla } 394*32cd2512SLokesh Vutla 395*32cd2512SLokesh Vutla /** 396*32cd2512SLokesh Vutla * ti_sci_probe() - Basic probe 397*32cd2512SLokesh Vutla * @dev: corresponding system controller interface device 398*32cd2512SLokesh Vutla * 399*32cd2512SLokesh Vutla * Return: 0 if all goes good, else appropriate error message. 400*32cd2512SLokesh Vutla */ 401*32cd2512SLokesh Vutla static int ti_sci_probe(struct udevice *dev) 402*32cd2512SLokesh Vutla { 403*32cd2512SLokesh Vutla struct ti_sci_info *info; 404*32cd2512SLokesh Vutla int ret; 405*32cd2512SLokesh Vutla 406*32cd2512SLokesh Vutla debug("%s(dev=%p)\n", __func__, dev); 407*32cd2512SLokesh Vutla 408*32cd2512SLokesh Vutla info = dev_get_priv(dev); 409*32cd2512SLokesh Vutla info->desc = (void *)dev_get_driver_data(dev); 410*32cd2512SLokesh Vutla 411*32cd2512SLokesh Vutla ret = ti_sci_of_to_info(dev, info); 412*32cd2512SLokesh Vutla if (ret) { 413*32cd2512SLokesh Vutla dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret); 414*32cd2512SLokesh Vutla return ret; 415*32cd2512SLokesh Vutla } 416*32cd2512SLokesh Vutla 417*32cd2512SLokesh Vutla info->dev = dev; 418*32cd2512SLokesh Vutla info->seq = 0xA; 419*32cd2512SLokesh Vutla 420*32cd2512SLokesh Vutla list_add_tail(&info->list, &ti_sci_list); 421*32cd2512SLokesh Vutla 422*32cd2512SLokesh Vutla ret = ti_sci_cmd_get_revision(&info->handle); 423*32cd2512SLokesh Vutla 424*32cd2512SLokesh Vutla return ret; 425*32cd2512SLokesh Vutla } 426*32cd2512SLokesh Vutla 427*32cd2512SLokesh Vutla /* Description for AM654 */ 428*32cd2512SLokesh Vutla static const struct ti_sci_desc ti_sci_sysfw_am654_desc = { 429*32cd2512SLokesh Vutla .host_id = 4, 430*32cd2512SLokesh Vutla .max_rx_timeout_us = 1000000, 431*32cd2512SLokesh Vutla .max_msg_size = 60, 432*32cd2512SLokesh Vutla }; 433*32cd2512SLokesh Vutla 434*32cd2512SLokesh Vutla static const struct udevice_id ti_sci_ids[] = { 435*32cd2512SLokesh Vutla { 436*32cd2512SLokesh Vutla .compatible = "ti,k2g-sci", 437*32cd2512SLokesh Vutla .data = (ulong)&ti_sci_sysfw_am654_desc 438*32cd2512SLokesh Vutla }, 439*32cd2512SLokesh Vutla { /* Sentinel */ }, 440*32cd2512SLokesh Vutla }; 441*32cd2512SLokesh Vutla 442*32cd2512SLokesh Vutla U_BOOT_DRIVER(ti_sci) = { 443*32cd2512SLokesh Vutla .name = "ti_sci", 444*32cd2512SLokesh Vutla .id = UCLASS_FIRMWARE, 445*32cd2512SLokesh Vutla .of_match = ti_sci_ids, 446*32cd2512SLokesh Vutla .probe = ti_sci_probe, 447*32cd2512SLokesh Vutla .priv_auto_alloc_size = sizeof(struct ti_sci_info), 448*32cd2512SLokesh Vutla }; 449