1 /*
2 * TISCI core library
3 *
4 * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
5 * Lokesh Vutla <lokeshvutla@ti.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the
17 * distribution.
18 *
19 * Neither the name of Texas Instruments Incorporated nor the names of
20 * its contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
36 #include <string.h>
37 #include <sec_proxy.h>
38 #include <tisci.h>
39 #include <tisci_protocol.h>
40 #include <socinfo.h>
42 static int seq = 0;
44 void ti_sci_setup_header(struct ti_sci_msg_hdr *hdr, uint16_t type,
45 uint32_t flags)
46 {
47 hdr->type = type;
48 hdr->host = soc_info.host_id;
49 hdr->seq = seq++;
50 hdr->flags = TI_SCI_FLAG_REQ_ACK_ON_PROCESSED | flags;
51 }
53 int ti_sci_xfer_msg(struct k3_sec_proxy_msg *msg)
54 {
55 int ret;
57 if (!msg->len || !msg->buf)
58 return -1;
60 ret = k3_sec_proxy_send(msg);
61 if (ret)
62 return ret;
64 memset(msg->buf, 0, msg->len);
65 ret = k3_sec_proxy_recv(msg);
66 if (ret)
67 return ret;
69 if (!ti_sci_is_response_ack(msg->buf))
70 return -1;
72 return 0;
73 }
75 int ti_sci_init(void)
76 {
77 struct ti_sci_msg_resp_version *version;
78 struct ti_sci_version_info *glb_ver;
79 uint8_t buf[SEC_PROXY_MAX_MSG_SIZE];
80 struct k3_sec_proxy_msg msg;
81 int ret;
83 memset(buf, 0, sizeof(buf));
84 ti_sci_setup_header((struct ti_sci_msg_hdr *)buf, TI_SCI_MSG_VERSION,
85 0);
87 msg.len = sizeof(struct ti_sci_msg_hdr);
88 msg.buf = buf;
89 ret = ti_sci_xfer_msg(&msg);
90 if (ret)
91 return ret;
93 version = (struct ti_sci_msg_resp_version *)buf;
94 glb_ver = &soc_info.sci_info.version;
95 glb_ver->abi_major = version->abi_major;
96 glb_ver->abi_minor = version->abi_minor;
97 glb_ver->firmware_version = version->version;
98 strncpy(glb_ver->firmware_description, version->firmware_description,
99 sizeof(glb_ver->firmware_description));
101 return 0;
102 }
104 int ti_sci_cmd_get_range(uint16_t type, uint16_t subtype, uint16_t host_id,
105 struct ti_sci_rm_desc *desc)
106 {
107 struct ti_sci_msg_resp_get_resource_range *resp;
108 struct ti_sci_msg_req_get_resource_range *req;
109 uint8_t buf[SEC_PROXY_MAX_MSG_SIZE];
110 struct k3_sec_proxy_msg msg;
111 int ret = 0;
113 memset(buf, 0, sizeof(buf));
114 ti_sci_setup_header((struct ti_sci_msg_hdr *)buf,
115 TI_SCI_MSG_GET_RESOURCE_RANGE, 0);
116 req = (struct ti_sci_msg_req_get_resource_range *)buf;
117 req->type = type;
118 req->subtype = subtype;
119 req->secondary_host = host_id;
121 msg.len = sizeof(*req);
122 msg.buf = buf;
123 ret = ti_sci_xfer_msg(&msg);
124 if (ret)
125 return ret;
127 resp = (struct ti_sci_msg_resp_get_resource_range *)buf;
128 desc->start = resp->range_start;
129 desc->num = resp->range_num;
130 desc->start_sec = resp->range_start_sec;
131 desc->num_sec = resp->range_num_sec;
133 return 0;
134 }