blob: eba03991b68f4615039cbdb04db7d3aca337c7c5 [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
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080014
15static bool is_mailbox_cmdbuf_full(uint32_t cin)
16{
17 uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
18
19 return (((cin + 1U) % MBOX_CMD_BUFFER_SIZE) == cout);
20}
21
22static bool is_mailbox_cmdbuf_empty(uint32_t cin)
23{
24 uint32_t cout = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
25
26 return (((cout + 1U) % MBOX_CMD_BUFFER_SIZE) == cin);
27}
28
29static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
30{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +080031 unsigned int timeout = 200U;
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080032
33 do {
34 if (is_mailbox_cmdbuf_empty(cin)) {
35 break;
36 }
37 mdelay(10U);
38 } while (--timeout != 0U);
39
40 if (timeout == 0U) {
41 return MBOX_TIMEOUT;
42 }
43
44 return MBOX_RET_OK;
45}
46
47static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
48 uint32_t data,
49 bool *is_doorbell_triggered)
50{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +080051 unsigned int timeout = 100U;
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080052
53 do {
54 if (is_mailbox_cmdbuf_full(*cin)) {
55 if (!(*is_doorbell_triggered)) {
56 mmio_write_32(MBOX_OFFSET +
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +080057 MBOX_DOORBELL_TO_SDM, 1U);
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +080058 *is_doorbell_triggered = true;
59 }
60 mdelay(10U);
61 } else {
62 mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER +
63 (*cin * 4), data);
64 (*cin)++;
65 *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,
132 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 Asyrafi046e1f12020-02-12 19:57:44 +0800147 resp_data = mmio_read_32(MBOX_OFFSET +
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800148 MBOX_RESP_BUFFER + ((rout++)*4U));
Hadi Asyrafi616da772019-06-27 11:34:03 +0800149
150 rout %= MBOX_RESP_BUFFER_SIZE;
151 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
152
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +0800153
154 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800155 return MBOX_WRONG_ID;
156 }
157
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +0800158 *job_id = MBOX_RESP_JOB_ID(resp_data);
159
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800160 ret_resp_len = MBOX_RESP_LEN(resp_data);
161
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800162 if (ret_resp_len != 0U) {
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800163 ret_resp_len = iterate_resp(ret_resp_len, response,
164 resp_len);
165 }
166
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800167 if (MBOX_RESP_ERR(resp_data) > 0U) {
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800168 INFO("Error in response: %x\n", resp_data);
Chee Hong Ang5bc87bc2020-05-11 11:23:21 +0800169 return -MBOX_RESP_ERR(resp_data);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800170 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800171
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800172 return ret_resp_len;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800173 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800174 return MBOX_NO_RESPONSE;
175}
176
177
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800178int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
179 unsigned int resp_len)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800180{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800181 unsigned int timeout = 40U;
182 unsigned int sdm_loop = 255U;
183 unsigned int ret_resp_len;
184 uint32_t rin;
185 uint32_t rout;
186 uint32_t resp_data;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800187
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800188 while (sdm_loop != 0U) {
Hadi Asyrafia91818f2019-11-12 14:55:26 +0800189
Chee Hong Ang64740962020-05-11 00:55:01 +0800190 do {
191 if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800192 == 1U) {
Chee Hong Ang64740962020-05-11 00:55:01 +0800193 break;
194 }
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800195 mdelay(10U);
Chee Hong Ang64740962020-05-11 00:55:01 +0800196 } while (--timeout != 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800197
Chee Hong Ang64740962020-05-11 00:55:01 +0800198 if (timeout == 0U) {
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800199 break;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800200 }
201
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800202 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800203
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800204 if ((urgent & 1U) != 0U) {
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800205 mdelay(5U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800206 if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
207 MBOX_STATUS_UA_MASK) ^
208 (urgent & MBOX_STATUS_UA_MASK)) {
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800209 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800210 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800211 }
212
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800213 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800214 INFO("Error: Mailbox did not get UA");
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800215 return MBOX_RET_ERROR;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800216 }
217
218 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
219 rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
220
221 while (rout != rin) {
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800222 resp_data = mmio_read_32(MBOX_OFFSET +
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800223 MBOX_RESP_BUFFER + ((rout++)*4U));
Hadi Asyrafi616da772019-06-27 11:34:03 +0800224
225 rout %= MBOX_RESP_BUFFER_SIZE;
226 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
227
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800228 if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800229 || MBOX_RESP_JOB_ID(resp_data) != job_id) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800230 continue;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800231 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800232
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800233 ret_resp_len = MBOX_RESP_LEN(resp_data);
234
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800235 if (ret_resp_len != 0U) {
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800236 ret_resp_len = iterate_resp(ret_resp_len,
237 response,
238 resp_len);
239 }
240
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800241 if (MBOX_RESP_ERR(resp_data) > 0U) {
Abdul Halim, Muhammad Hadi Asyrafi046e1f12020-02-12 19:57:44 +0800242 INFO("Error in response: %x\n", resp_data);
243 return -MBOX_RESP_ERR(resp_data);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800244 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800245
Chee Hong Ang39d137b2020-05-11 00:40:18 +0800246 return ret_resp_len;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800247 }
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800248
249 sdm_loop--;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800250 }
Abdul Halim, Muhammad Hadi Asyrafi14a1d432020-06-02 01:05:24 +0800251
252 INFO("Timed out waiting for SDM\n");
253 return MBOX_TIMEOUT;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800254}
255
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800256unsigned int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
257 unsigned int resp_len)
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800258{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800259 unsigned int timeout, total_resp_len = 0U;
260 uint32_t resp_data;
261 uint32_t rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
262 uint32_t rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800263
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800264 while (mbox_resp_len > 0U) {
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800265 timeout = 100U;
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800266 mbox_resp_len--;
267 resp_data = mmio_read_32(MBOX_OFFSET +
268 MBOX_RESP_BUFFER +
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800269 (rout)*4U);
270
271 if ((resp_buf != NULL) && (resp_len != 0U)) {
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800272 *(resp_buf + total_resp_len)
273 = resp_data;
274 resp_len--;
275 total_resp_len++;
276 }
277 rout++;
278 rout %= MBOX_RESP_BUFFER_SIZE;
279 mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
280
281 do {
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800282 rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
Chee Hong Ang64740962020-05-11 00:55:01 +0800283 if (rout == rin) {
Abdul Halim, Muhammad Hadi Asyrafi7d66e142020-06-02 01:06:33 +0800284 mdelay(10U);
Chee Hong Ang64740962020-05-11 00:55:01 +0800285 } else {
286 break;
287 }
288 timeout--;
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800289 } while ((mbox_resp_len > 0U) && (timeout != 0U));
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800290
Chee Hong Ang64740962020-05-11 00:55:01 +0800291 if (timeout == 0U) {
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800292 INFO("Timed out waiting for SDM\n");
293 return MBOX_TIMEOUT;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800294 }
295 }
Abdul Halim, Muhammad Hadi Asyrafi94fae382020-04-29 22:26:40 +0800296 return total_resp_len;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800297}
298
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800299int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
300 unsigned int len, unsigned int indirect)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800301{
Abdul Halim, Muhammad Hadi Asyrafi20a07f32020-05-18 11:16:48 +0800302 int status;
303
304 status = fill_mailbox_circular_buffer(
305 MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
306 MBOX_JOB_ID_CMD(*job_id) |
307 MBOX_CMD_LEN_CMD(len) |
308 MBOX_INDIRECT(indirect) |
309 cmd, args, len);
310 if (status < 0) {
311 return status;
312 }
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800313
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800314 *job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800315
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800316 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800317}
318
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800319int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
320 unsigned int len, uint32_t urgent, uint32_t *response,
321 unsigned int resp_len)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800322{
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800323 int status = 0;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800324
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800325 if (urgent != 0U) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800326 urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
327 MBOX_STATUS_UA_MASK;
328 mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800329 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800330 }
331
332 else {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800333 status = fill_mailbox_circular_buffer(
334 MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
335 MBOX_JOB_ID_CMD(job_id) |
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800336 MBOX_CMD_LEN_CMD(len) |
Hadi Asyrafi616da772019-06-27 11:34:03 +0800337 cmd, args, len);
338 }
339
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800340 if (status != 0) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800341 return status;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800342 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800343
Hadi Asyrafi9dfc0472019-11-12 16:39:46 +0800344 status = mailbox_poll_response(job_id, urgent, response, resp_len);
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800345
346 return status;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800347}
348
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800349void mailbox_clear_response(void)
350{
351 mmio_write_32(MBOX_OFFSET + MBOX_ROUT,
352 mmio_read_32(MBOX_OFFSET + MBOX_RIN));
353}
354
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800355void mailbox_set_int(uint32_t interrupt)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800356{
357
358 mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
359 MBOX_UAE_BIT(interrupt));
360}
361
362
363void mailbox_set_qspi_open(void)
364{
365 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800366 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, NULL, 0U,
367 CMD_CASUAL, NULL, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800368}
369
370void mailbox_set_qspi_direct(void)
371{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800372 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, NULL, 0U,
373 CMD_CASUAL, NULL, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800374}
375
376void mailbox_set_qspi_close(void)
377{
378 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800379 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, NULL, 0U,
380 CMD_CASUAL, NULL, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800381}
382
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800383void mailbox_qspi_set_cs(uint32_t device_select)
Hadi Asyrafi616da772019-06-27 11:34:03 +0800384{
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800385 uint32_t cs_setting;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800386
387 /* QSPI device select settings at 31:28 */
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800388 cs_setting = (device_select << 28);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800389 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
390 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800391 1U, CMD_CASUAL, NULL, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800392}
393
394void mailbox_reset_cold(void)
395{
396 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800397 mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, NULL, 0U,
398 CMD_CASUAL, NULL, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800399}
400
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800401int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, unsigned int resp_buf_len)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800402{
403 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800404 NULL, 0U, CMD_CASUAL, resp_buf,
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800405 resp_buf_len);
406}
407
408struct rsu_status_info {
409 uint64_t current_image;
410 uint64_t fail_image;
411 uint32_t state;
412 uint32_t version;
413 uint32_t error_location;
414 uint32_t error_details;
415 uint32_t retry_counter;
416};
417
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800418int mailbox_rsu_status(uint32_t *resp_buf, unsigned int resp_buf_len)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800419{
420 int ret;
421 struct rsu_status_info *info = (struct rsu_status_info *)resp_buf;
422
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800423 info->retry_counter = ~0U;
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800424
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800425 ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0U,
426 CMD_CASUAL, resp_buf,
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800427 resp_buf_len);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800428
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800429 if (ret < 0) {
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800430 return ret;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800431 }
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800432
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800433 if (info->retry_counter != ~0U) {
434 if ((info->version & RSU_VERSION_ACMF_MASK) == 0U) {
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800435 info->version |= RSU_VERSION_ACMF;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800436 }
437 }
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800438
439 return ret;
440}
441
Abdul Halim, Muhammad Hadi Asyrafid84bfef2020-02-25 16:28:10 +0800442int mailbox_rsu_update(uint32_t *flash_offset)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800443{
444 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800445 flash_offset, 2U,
446 CMD_CASUAL, NULL, 0U);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800447}
448
Abdul Halim, Muhammad Hadi Asyrafid84bfef2020-02-25 16:28:10 +0800449int mailbox_hps_stage_notify(uint32_t execution_stage)
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800450{
451 return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY,
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800452 &execution_stage, 1U, CMD_CASUAL,
453 NULL, 0U);
Hadi Asyrafi593c4c52019-12-17 19:22:17 +0800454}
455
Hadi Asyrafi616da772019-06-27 11:34:03 +0800456int mailbox_init(void)
457{
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800458 int status;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800459
460 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
461 MBOX_INT_FLAG_UAE);
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800462 mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
463 mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
Hadi Asyrafia91818f2019-11-12 14:55:26 +0800464
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800465 status = mailbox_send_cmd(0U, MBOX_CMD_RESTART, NULL, 0U,
466 CMD_URGENT, NULL, 0U);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800467
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800468 if (status != 0) {
Hadi Asyrafi616da772019-06-27 11:34:03 +0800469 return status;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800470 }
Hadi Asyrafi616da772019-06-27 11:34:03 +0800471
Tien Hock, Loh527234a2019-10-30 14:54:25 +0800472 mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
473 MBOX_INT_FLAG_UAE);
Hadi Asyrafi616da772019-06-27 11:34:03 +0800474
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800475 return MBOX_RET_OK;
Hadi Asyrafi616da772019-06-27 11:34:03 +0800476}
477
Abdul Halim, Muhammad Hadi Asyrafie59b9992020-02-11 20:17:05 +0800478int intel_mailbox_get_config_status(uint32_t cmd)
Hadi Asyrafic5168162019-10-21 16:25:07 +0800479{
Abdul Halim, Muhammad Hadi Asyrafie59b9992020-02-11 20:17:05 +0800480 int status;
481 uint32_t res, response[6];
Hadi Asyrafic5168162019-10-21 16:25:07 +0800482
Abdul Halim, Muhammad Hadi Asyrafi118ab212020-10-15 15:27:18 +0800483 status = mailbox_send_cmd(MBOX_JOB_ID, cmd, NULL, 0U, CMD_CASUAL,
484 response, ARRAY_SIZE(response));
Hadi Asyrafic5168162019-10-21 16:25:07 +0800485
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800486 if (status < 0) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800487 return status;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800488 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800489
490 res = response[RECONFIG_STATUS_STATE];
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800491 if ((res != 0U) && (res != MBOX_CFGSTAT_STATE_CONFIG)) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800492 return res;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800493 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800494
495 res = response[RECONFIG_STATUS_PIN_STATUS];
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800496 if ((res & PIN_STATUS_NSTATUS) == 0U) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800497 return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800498 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800499
500 res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800501 if ((res & SOFTFUNC_STATUS_SEU_ERROR) != 0U) {
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800502 return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800503 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800504
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800505 if ((res & SOFTFUNC_STATUS_CONF_DONE) != 0U &&
506 (res & SOFTFUNC_STATUS_INIT_DONE) != 0U) {
Abdul Halim, Muhammad Hadi Asyrafib45f15e2020-05-14 15:32:43 +0800507 return MBOX_RET_OK;
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800508 }
Hadi Asyrafic5168162019-10-21 16:25:07 +0800509
Hadi Asyrafi2b9198d2019-11-12 15:03:00 +0800510 return MBOX_CFGSTAT_STATE_CONFIG;
Hadi Asyrafic5168162019-10-21 16:25:07 +0800511}
Hadi Asyrafi6aeb55d2019-12-24 14:43:22 +0800512
513int intel_mailbox_is_fpga_not_ready(void)
514{
515 int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS);
516
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800517 if ((ret != MBOX_RET_OK) && (ret != MBOX_CFGSTAT_STATE_CONFIG)) {
Hadi Asyrafi6aeb55d2019-12-24 14:43:22 +0800518 ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS);
Abdul Halim, Muhammad Hadi Asyrafi1b0e8cb2020-09-01 21:05:18 +0800519 }
Hadi Asyrafi6aeb55d2019-12-24 14:43:22 +0800520
521 return ret;
522}