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