blob: 79817e64c5de3db0c5307769c8d5b9cbb7a4c59f [file] [log] [blame]
Hadi Asyrafi616da772019-06-27 11:34:03 +08001/*
Siew Chin Limbf909842021-07-30 00:40:48 +08002 * Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
Hadi Asyrafi616da772019-06-27 11:34:03 +08003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <lib/mmio.h>
8#include <common/debug.h>
Hadi Asyrafia91818f2019-11-12 14:55:26 +08009#include <drivers/delay_timer.h>
Hadi Asyrafi616da772019-06-27 11:34:03 +080010
Hadi Asyrafi6f8a2b22019-10-23 18:34:14 +080011#include "socfpga_mailbox.h"
Hadi Asyrafic5168162019-10-21 16:25:07 +080012#include "socfpga_sip_svc.h"
Hadi Asyrafi616da772019-06-27 11:34:03 +080013
Sieu Mun Tangfd8a8ad2022-05-07 00:50:37 +080014static mailbox_payload_t mailbox_resp_payload;
15static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080016
17static bool is_mailbox_cmdbuf_full(uint32_t cin)
18{
19 uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
20
21 return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout);
22}
23
24static bool is_mailbox_cmdbuf_empty(uint32_t cin)
25{
26 uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
27
28 return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin);
29}
30
31static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
32{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +080033 unsigned int timeout = 200U;
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080034
35 do {
36 if (is_mailbox_cmdbuf_empty(cin)) {
37 break;
38 }
39 mdelay(10U);
40 } while (--timeout != 0U);
41
42 if (timeout == 0U) {
43 return MBOX_TIMEOUT;
44 }
45
46 return MBOX_RET_OK;
47}
48
49static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
50 uint32_t data,
51 bool *is_doorbell_triggered)
52{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +080053 unsigned int timeout = 100U;
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080054
55 do {
56 if (is_mailbox_cmdbuf_full(*cin)) {
57 if (!(*is_doorbell_triggered)) {
58 mmio_write_32(MBOX_OFFSET +
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +080059 MBOX_DOORBELL_TO_SDM, 1U);
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080060 *is_doorbell_triggered = true;
61 }
62 mdelay(10U);
63 } else {
Abdul Halim, Muhammad Hadi Asyrafi33b89d52020-06-05 15:12:29 +080064 mmio_write_32(MBOX_ENTRY_TO_ADDR(CMD, (*cin)++), data);
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080065 *cin %= MBOX_CMD_BUFFER_SIZE;
66 mmio_write_32(MBOX_OFFSET + MBOX_CIN, *cin);
67 break;
68 }
69 } while (--timeout != 0U);
70
71 if (timeout == 0U) {
72 return MBOX_TIMEOUT;
73 }
74
75 if (*is_doorbell_triggered) {
76 int ret = wait_for_mailbox_cmdbuf_empty(*cin);
77 return ret;
78 }
79
80 return MBOX_RET_OK;
81}
82
Abdul Halim, Muhammad Hadi Asyrafid84bfef2020-02-25 16:28:10 +080083static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +080084 unsigned int len)
Hadi Asyrafi616da772019-06-27 11:34:03 +080085{
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +080086 uint32_t sdm_read_offset, cmd_free_offset;
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +080087 unsigned int i;
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080088 int ret;
89 bool is_doorbell_triggered = false;
Hadi Asyrafi616da772019-06-27 11:34:03 +080090
91 cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +080092 sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
93
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080094 ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset,
95 header_cmd, &is_doorbell_triggered);
96 if (ret != 0) {
Chee Hong Ang5bc87bc2020-05-11 11:23:21 +080097 goto restart_mailbox;
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +080098 }
Hadi Asyrafi616da772019-06-27 11:34:03 +080099
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800100 for (i = 0U; i < len; i++) {
101 is_doorbell_triggered = false;
102 ret = write_mailbox_cmd_buffer(&cmd_free_offset,
103 sdm_read_offset, args[i],
104 &is_doorbell_triggered);
105 if (ret != 0) {
Chee Hong Ang5bc87bc2020-05-11 11:23:21 +0800106 goto restart_mailbox;
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800107 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800108 }
109
Siew Chin Limbf909842021-07-30 00:40:48 +0800110 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800111
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800112 return MBOX_RET_OK;
Chee Hong Ang5bc87bc2020-05-11 11:23:21 +0800113
114restart_mailbox:
115 /*
116 * Attempt to restart mailbox if the driver not able to write
117 * into mailbox command buffer
118 */
119 if (MBOX_CMD_MASK(header_cmd) != MBOX_CMD_RESTART) {
120 INFO("Mailbox timed out: Attempting mailbox reset\n");
121 ret = mailbox_init();
122
123 if (ret == MBOX_TIMEOUT) {
124 INFO("Error: Mailbox fail to restart\n");
125 }
126 }
127
128 return MBOX_TIMEOUT;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800129}
130
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800131int mailbox_read_response(unsigned int *job_id, uint32_t *response,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800132 unsigned int *resp_len)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800133{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800134 uint32_t rin;
135 uint32_t rout;
136 uint32_t resp_data;
137 unsigned int ret_resp_len;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800138
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800139 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
140 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
141 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800142
143 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
144 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
145
Hadi Asyrafia91818f2019-11-12 14:55:26 +0800146 if (rout != rin) {
Abdul Halim, Muhammad Hadi Asyrafi33b89d52020-06-05 15:12:29 +0800147 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
Hadi Asyrafi616da772019-06-27 11:34:03 +0800148
149 rout %= MBOX_RESP_BUFFER_SIZE;
150 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
151
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +0800152
153 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800154 return MBOX_WRONG_ID;
155 }
156
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +0800157 *job_id = MBOX_RESP_JOB_ID(resp_data);
158
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800159 ret_resp_len = MBOX_RESP_LEN(resp_data);
160
Sieu Mun Tang24682662022-02-19 21:49:48 +0800161 if (iterate_resp(ret_resp_len, response, resp_len)
162 != MBOX_RET_OK) {
163 return MBOX_TIMEOUT;
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800164 }
165
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800166 if (MBOX_RESP_ERR(resp_data) > 0U) {
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800167 INFO("Error in response: %x\n", resp_data);
Chee Hong Ang5bc87bc2020-05-11 11:23:21 +0800168 return -MBOX_RESP_ERR(resp_data);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800169 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800170
Sieu Mun Tang24682662022-02-19 21:49:48 +0800171 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800172 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800173 return MBOX_NO_RESPONSE;
174}
175
Sieu Mun Tangfd8a8ad2022-05-07 00:50:37 +0800176int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
177 uint32_t *response, unsigned int *resp_len,
178 uint8_t ignore_client_id)
179{
180 uint32_t rin;
181 uint32_t rout;
182 uint32_t resp_data;
183 uint32_t ret_resp_len = 0;
184 uint8_t is_done = 0;
185
186 if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
187 ret_resp_len = MBOX_RESP_LEN(
188 mailbox_resp_ctr.payload->header) -
189 mailbox_resp_ctr.index;
190 }
191
192 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
193 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
194 }
195
196 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
197 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
198
199 while (rout != rin && !is_done) {
200
201 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
202
203 rout %= MBOX_RESP_BUFFER_SIZE;
204 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
205 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
206
207 if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
208 mailbox_resp_ctr.payload->data[mailbox_resp_ctr.index] = resp_data;
209 mailbox_resp_ctr.index++;
210 ret_resp_len--;
211 } else {
212 if (!ignore_client_id) {
213 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
214 *resp_len = 0;
215 return MBOX_WRONG_ID;
216 }
217 }
218
219 *job_id = MBOX_RESP_JOB_ID(resp_data);
220 ret_resp_len = MBOX_RESP_LEN(resp_data);
221 mailbox_resp_ctr.payload->header = resp_data;
222 mailbox_resp_ctr.flag |= MBOX_PAYLOAD_FLAG_BUSY;
223 }
224
225 if (ret_resp_len == 0) {
226 is_done = 1;
227 }
228 }
229
230 if (is_done != 0) {
231
232 /* copy header data to input address if applicable */
233 if (header != 0) {
234 *header = mailbox_resp_ctr.payload->header;
235 }
236
237 /* copy response data to input buffer if applicable */
238 ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
Sieu Mun Tangc9b11d22022-07-04 22:34:32 +0800239 if ((ret_resp_len > 0) && (response != NULL) && (resp_len != NULL)) {
Sieu Mun Tangfd8a8ad2022-05-07 00:50:37 +0800240 if (*resp_len > ret_resp_len) {
241 *resp_len = ret_resp_len;
242 }
243
244 memcpy((uint8_t *) response,
245 (uint8_t *) mailbox_resp_ctr.payload->data,
246 *resp_len * MBOX_WORD_BYTE);
247 }
248
249 /* reset async response param */
250 mailbox_resp_ctr.index = 0;
251 mailbox_resp_ctr.flag = 0;
252
253 if (MBOX_RESP_ERR(mailbox_resp_ctr.payload->header) > 0U) {
254 INFO("Error in async response: %x\n",
255 mailbox_resp_ctr.payload->header);
256 return -MBOX_RESP_ERR(mailbox_resp_ctr.payload->header);
257 }
258
259 return MBOX_RET_OK;
260 }
261
262 *resp_len = 0;
263 return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
264}
Hadi Asyrafi616da772019-06-27 11:34:03 +0800265
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800266int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800267 unsigned int *resp_len)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800268{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800269 unsigned int timeout = 40U;
270 unsigned int sdm_loop = 255U;
271 unsigned int ret_resp_len;
272 uint32_t rin;
273 uint32_t rout;
274 uint32_t resp_data;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800275
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800276 while (sdm_loop != 0U) {
Hadi Asyrafia91818f2019-11-12 14:55:26 +0800277
Chee Hong Ang64740962020-05-11 00:55:01 +0800278 do {
279 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800280 == 1U) {
Chee Hong Ang64740962020-05-11 00:55:01 +0800281 break;
282 }
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800283 mdelay(10U);
Chee Hong Ang64740962020-05-11 00:55:01 +0800284 } while (--timeout != 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800285
Chee Hong Ang64740962020-05-11 00:55:01 +0800286 if (timeout == 0U) {
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800287 break;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800288 }
289
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800290 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800291
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800292 if ((urgent & 1U) != 0U) {
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800293 mdelay(5U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800294 if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
295 MBOX_STATUS_UA_MASK) ^
296 (urgent & MBOX_STATUS_UA_MASK)) {
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800297 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800298 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800299 }
300
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800301 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800302 INFO("Error: Mailbox did not get UA");
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800303 return MBOX_RET_ERROR;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800304 }
305
306 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
307 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
308
309 while (rout != rin) {
Abdul Halim, Muhammad Hadi Asyrafi33b89d52020-06-05 15:12:29 +0800310 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP,
311 (rout)++));
Hadi Asyrafi616da772019-06-27 11:34:03 +0800312
313 rout %= MBOX_RESP_BUFFER_SIZE;
314 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
315
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800316 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800317 || MBOX_RESP_JOB_ID(resp_data) != job_id) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800318 continue;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800319 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800320
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800321 ret_resp_len = MBOX_RESP_LEN(resp_data);
322
Sieu Mun Tang24682662022-02-19 21:49:48 +0800323 if (iterate_resp(ret_resp_len, response, resp_len)
324 != MBOX_RET_OK) {
325 return MBOX_TIMEOUT;
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800326 }
327
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800328 if (MBOX_RESP_ERR(resp_data) > 0U) {
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800329 INFO("Error in response: %x\n", resp_data);
330 return -MBOX_RESP_ERR(resp_data);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800331 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800332
Sieu Mun Tang24682662022-02-19 21:49:48 +0800333 return MBOX_RET_OK;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800334 }
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800335
336 sdm_loop--;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800337 }
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800338
339 INFO("Timed out waiting for SDM\n");
340 return MBOX_TIMEOUT;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800341}
342
Sieu Mun Tang24682662022-02-19 21:49:48 +0800343int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
344 unsigned int *resp_len)
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800345{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800346 unsigned int timeout, total_resp_len = 0U;
347 uint32_t resp_data;
348 uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
349 uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800350
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800351 while (mbox_resp_len > 0U) {
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800352 timeout = 100U;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800353 mbox_resp_len--;
Abdul Halim, Muhammad Hadi Asyrafi33b89d52020-06-05 15:12:29 +0800354 resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800355
Sieu Mun Tang24682662022-02-19 21:49:48 +0800356 if ((resp_buf != NULL) && (resp_len != NULL)
357 && (*resp_len != 0U)) {
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800358 *(resp_buf + total_resp_len)
359 = resp_data;
Sieu Mun Tang24682662022-02-19 21:49:48 +0800360 *resp_len = *resp_len - 1;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800361 total_resp_len++;
362 }
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800363 rout %= MBOX_RESP_BUFFER_SIZE;
364 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
365
366 do {
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800367 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
Chee Hong Ang64740962020-05-11 00:55:01 +0800368 if (rout == rin) {
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800369 mdelay(10U);
Chee Hong Ang64740962020-05-11 00:55:01 +0800370 } else {
371 break;
372 }
373 timeout--;
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800374 } while ((mbox_resp_len > 0U) && (timeout != 0U));
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800375
Chee Hong Ang64740962020-05-11 00:55:01 +0800376 if (timeout == 0U) {
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800377 INFO("Timed out waiting for SDM\n");
378 return MBOX_TIMEOUT;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800379 }
380 }
Sieu Mun Tang24682662022-02-19 21:49:48 +0800381
382 if (resp_len)
383 *resp_len = total_resp_len;
384
385 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800386}
387
Sieu Mun Tang5d187c02022-05-10 23:26:57 +0800388int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
389 unsigned int len)
390{
391 return fill_mailbox_circular_buffer(header_cmd, args, len);
392}
393
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800394int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
395 unsigned int len, unsigned int indirect)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800396{
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +0800397 int status;
398
399 status = fill_mailbox_circular_buffer(
400 MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
401 MBOX_JOB_ID_CMD(*job_id) |
402 MBOX_CMD_LEN_CMD(len) |
403 MBOX_INDIRECT(indirect) |
404 cmd, args, len);
405 if (status < 0) {
406 return status;
407 }
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800408
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800409 *job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800410
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800411 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800412}
413
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800414int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
415 unsigned int len, uint32_t urgent, uint32_t *response,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800416 unsigned int *resp_len)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800417{
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800418 int status = 0;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800419
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800420 if (urgent != 0U) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800421 urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
422 MBOX_STATUS_UA_MASK;
423 mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800424 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800425 }
426
427 else {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800428 status = fill_mailbox_circular_buffer(
429 MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
430 MBOX_JOB_ID_CMD(job_id) |
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800431 MBOX_CMD_LEN_CMD(len) |
Hadi Asyrafi616da772019-06-27 11:34:03 +0800432 cmd, args, len);
433 }
434
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800435 if (status != 0) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800436 return status;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800437 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800438
Hadi Asyrafi9dfc0472019-11-12 16:39:46 +0800439 status = mailbox_poll_response(job_id, urgent, response, resp_len);
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800440
441 return status;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800442}
443
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800444void mailbox_clear_response(void)
445{
446 mmio_write_32(MBOX_OFFSET + MBOX_ROUT,
447 mmio_read_32(MBOX_OFFSET + MBOX_RIN));
448}
449
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800450void mailbox_set_int(uint32_t interrupt)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800451{
452
453 mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
454 MBOX_UAE_BIT(interrupt));
455}
456
457
458void mailbox_set_qspi_open(void)
459{
460 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800461 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800462 CMD_CASUAL, NULL, NULL);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800463}
464
465void mailbox_set_qspi_direct(void)
466{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800467 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800468 CMD_CASUAL, NULL, NULL);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800469}
470
471void mailbox_set_qspi_close(void)
472{
473 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800474 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800475 CMD_CASUAL, NULL, NULL);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800476}
477
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800478void mailbox_qspi_set_cs(uint32_t device_select)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800479{
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800480 uint32_t cs_setting;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800481
482 /* QSPI device select settings at 31:28 */
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800483 cs_setting = (device_select << 28);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800484 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
485 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800486 1U, CMD_CASUAL, NULL, NULL);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800487}
488
Abdul Halim, Muhammad Hadi Asyrafiae4cd3a2020-10-06 20:09:53 +0800489void mailbox_hps_qspi_enable(void)
490{
491 mailbox_set_qspi_open();
492 mailbox_set_qspi_direct();
493}
494
Hadi Asyrafi616da772019-06-27 11:34:03 +0800495void mailbox_reset_cold(void)
496{
497 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800498 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800499 CMD_CASUAL, NULL, NULL);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800500}
501
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800502int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800503{
504 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800505 NULL, 0U, CMD_CASUAL, resp_buf,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800506 &resp_buf_len);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800507}
508
509struct rsu_status_info {
510 uint64_t current_image;
511 uint64_t fail_image;
512 uint32_t state;
513 uint32_t version;
514 uint32_t error_location;
515 uint32_t error_details;
516 uint32_t retry_counter;
517};
518
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800519int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800520{
521 int ret;
522 struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
523
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800524 info->retry_counter = ~0U;
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800525
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800526 ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U,
527 CMD_CASUAL, resp_buf,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800528 &resp_buf_len);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800529
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800530 if (ret < 0) {
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800531 return ret;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800532 }
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800533
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800534 if (info->retry_counter != ~0U) {
535 if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) {
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800536 info->version |= RSU_VERSION_ACMF;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800537 }
538 }
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800539
540 return ret;
541}
542
Abdul Halim, Muhammad Hadi Asyrafid84bfef2020-02-25 16:28:10 +0800543int mailbox_rsu_update(uint32_t *flash_offset)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800544{
545 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800546 flash_offset, 2U,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800547 CMD_CASUAL, NULL, NULL);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800548}
549
Abdul Halim, Muhammad Hadi Asyrafid84bfef2020-02-25 16:28:10 +0800550int mailbox_hps_stage_notify(uint32_t execution_stage)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800551{
552 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800553 &execution_stage, 1U, CMD_CASUAL,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800554 NULL, NULL);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800555}
556
Hadi Asyrafi616da772019-06-27 11:34:03 +0800557int mailbox_init(void)
558{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800559 int status;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800560
561 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
562 MBOX_INT_FLAG_UAE);
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800563 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
564 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
Hadi Asyrafia91818f2019-11-12 14:55:26 +0800565
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800566 status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800567 CMD_URGENT, NULL, NULL);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800568
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800569 if (status != 0) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800570 return status;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800571 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800572
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800573 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
574 MBOX_INT_FLAG_UAE);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800575
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800576 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800577}
578
Sieu Mun Tang24682662022-02-19 21:49:48 +0800579int intel_mailbox_get_config_status(uint32_t cmd, bool init_done)
Hadi Asyrafic5168162019-10-21 16:25:07 +0800580{
Abdul Halim, Muhammad Hadi Asyrafie59b9992020-02-11 20:17:05 +0800581 int status;
582 uint32_t res, response[6];
Sieu Mun Tang24682662022-02-19 21:49:48 +0800583 unsigned int resp_len = ARRAY_SIZE(response);
Hadi Asyrafic5168162019-10-21 16:25:07 +0800584
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800585 status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL,
Sieu Mun Tang24682662022-02-19 21:49:48 +0800586 response, &resp_len);
Hadi Asyrafic5168162019-10-21 16:25:07 +0800587
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800588 if (status < 0) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800589 return status;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800590 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800591
592 res = response[RECONFIG_STATUS_STATE];
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800593 if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800594 return res;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800595 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800596
597 res = response[RECONFIG_STATUS_PIN_STATUS];
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800598 if ((res & PIN_STATUS_NSTATUS) == 0U) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800599 return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800600 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800601
602 res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800603 if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800604 return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800605 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800606
Abdul Halim, Muhammad Hadi Asyrafi37c70762020-11-20 11:41:59 +0800607 if ((res & SOFTFUNC_STATUS_CONF_DONE) == 0U) {
Sieu Mun Tang24682662022-02-19 21:49:48 +0800608 return MBOX_CFGSTAT_STATE_CONFIG;
Abdul Halim, Muhammad Hadi Asyrafi37c70762020-11-20 11:41:59 +0800609 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800610
Abdul Halim, Muhammad Hadi Asyrafi37c70762020-11-20 11:41:59 +0800611 if (init_done && (res & SOFTFUNC_STATUS_INIT_DONE) == 0U) {
Sieu Mun Tang24682662022-02-19 21:49:48 +0800612 return MBOX_CFGSTAT_STATE_CONFIG;
Abdul Halim, Muhammad Hadi Asyrafi37c70762020-11-20 11:41:59 +0800613 }
Sieu Mun Tang24682662022-02-19 21:49:48 +0800614
615 return MBOX_RET_OK;
Hadi Asyrafic5168162019-10-21 16:25:07 +0800616}
Hadi Asyrafi6aeb55d2019-12-24 14:43:22 +0800617
618int intel_mailbox_is_fpga_not_ready(void)
619{
Sieu Mun Tang24682662022-02-19 21:49:48 +0800620 int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS, true);
Hadi Asyrafi6aeb55d2019-12-24 14:43:22 +0800621
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800622 if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
Sieu Mun Tang24682662022-02-19 21:49:48 +0800623 ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS,
624 false);
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800625 }
Hadi Asyrafi6aeb55d2019-12-24 14:43:22 +0800626
627 return ret;
628}
Kris Chapline768dfa2021-06-25 11:31:52 +0100629
630int mailbox_hwmon_readtemp(uint32_t chan, uint32_t *resp_buf)
631{
632 unsigned int resp_len = sizeof(resp_buf);
633
634 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READTEMP, &chan, 1U,
635 CMD_CASUAL, resp_buf,
636 &resp_len);
637
638}
639
640int mailbox_hwmon_readvolt(uint32_t chan, uint32_t *resp_buf)
641{
642 unsigned int resp_len = sizeof(resp_buf);
643
644 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HWMON_READVOLT, &chan, 1U,
645 CMD_CASUAL, resp_buf,
646 &resp_len);
647}