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