1 /*
2  * Copyright (c) 2017-2020, Broadcom
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch_helpers.h>
8 #include <common/bl_common.h>
9 #include <drivers/delay_timer.h>
10 
11 #include <platform_def.h>
12 #include <scp.h>
13 #include <scp_cmd.h>
14 
15 #include "m0_ipc.h"
16 
17 /*
18  * Reads a response from CRMU MAILBOX
19  * Assumes that access has been granted and locked.
20  * Note that this is just a temporary implementation until
21  * channels are introduced
22  */
scp_read_response(crmu_response_t * resp)23 static void scp_read_response(crmu_response_t *resp)
24 {
25 	uint32_t code;
26 
27 	code = mmio_read_32(CRMU_MAIL_BOX0);
28 	resp->completed = code & MCU_IPC_CMD_DONE_MASK;
29 	resp->cmd = code & SCP_CMD_MASK;
30 	resp->ret = (code & MCU_IPC_CMD_REPLY_MASK) >> MCU_IPC_CMD_REPLY_SHIFT;
31 }
32 
33 /*
34  * Send a command to SCP and wait for timeout us.
35  * Return:  0 on success
36  *         -1 if there was no proper reply from SCP
37  *         >0 if there was a response from MCU, but
38  *            command completed with an error.
39  */
scp_send_cmd(uint32_t cmd,uint32_t param,uint32_t timeout)40 int scp_send_cmd(uint32_t cmd, uint32_t param, uint32_t timeout)
41 {
42 	int ret = -1;
43 
44 	mmio_write_32(CRMU_MAIL_BOX0, cmd);
45 	mmio_write_32(CRMU_MAIL_BOX1, param);
46 	do {
47 		crmu_response_t scp_resp;
48 
49 		udelay(1);
50 		scp_read_response(&scp_resp);
51 		if (scp_resp.completed &&
52 			(scp_resp.cmd == cmd)) {
53 			/* This command has completed */
54 			ret = scp_resp.ret;
55 			break;
56 		}
57 	} while (--timeout);
58 
59 	return ret;
60 }
61