xref: /rk3399_ARM-atf/plat/socionext/uniphier/uniphier_scp.c (revision 0281e60c3d59d7552a589ecae1b1223b9dededd1)
1d8e919c7SMasahiro Yamada /*
2*577b2441SMasahiro Yamada  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3d8e919c7SMasahiro Yamada  *
4d8e919c7SMasahiro Yamada  * SPDX-License-Identifier: BSD-3-Clause
5d8e919c7SMasahiro Yamada  */
6d8e919c7SMasahiro Yamada 
709d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
809d40e0eSAntonio Nino Diaz #include <lib/utils_def.h>
9d8e919c7SMasahiro Yamada 
10d8e919c7SMasahiro Yamada #include "uniphier.h"
11d8e919c7SMasahiro Yamada 
12d8e919c7SMasahiro Yamada #define UNIPHIER_ROM_RSV3		0x5980120c
13d8e919c7SMasahiro Yamada 
14d8e919c7SMasahiro Yamada #define UNIPHIER_STMBE2COM		0x5f800030
15e6a90288SDai Okamura #define UNIPHIER_STMTOBEIRQ		0x5f800060
16d8e919c7SMasahiro Yamada #define UNIPHIER_BETOSTMIRQ0PT		0x5f800070
17e6a90288SDai Okamura #define UNIPHIER_BEIRQCLRPT		0x5f800072
18d8e919c7SMasahiro Yamada 
19d8e919c7SMasahiro Yamada #define UNIPHIER_SCP_READY_MAGIC	0x0000b6a5
20d8e919c7SMasahiro Yamada 
21d8e919c7SMasahiro Yamada #define UNIPHIER_SCP_PACKET_START	0xA0
22d8e919c7SMasahiro Yamada #define UNIPHIER_SCP_PACKET_END		0xA5
23d8e919c7SMasahiro Yamada #define UNIPHIER_SCP_PACKET_ESC		0xA6
24d8e919c7SMasahiro Yamada #define UNIPHIER_SCP_IS_CTRL_CODE(c)	(0xA0 <= (c) && (c) <= 0xA6)
25d8e919c7SMasahiro Yamada 
uniphier_scp_is_running(void)26d8e919c7SMasahiro Yamada int uniphier_scp_is_running(void)
27d8e919c7SMasahiro Yamada {
28d8e919c7SMasahiro Yamada 	return mmio_read_32(UNIPHIER_STMBE2COM) == UNIPHIER_SCP_READY_MAGIC;
29d8e919c7SMasahiro Yamada }
30d8e919c7SMasahiro Yamada 
uniphier_scp_start(uint32_t scp_base)31*577b2441SMasahiro Yamada void uniphier_scp_start(uint32_t scp_base)
32d8e919c7SMasahiro Yamada {
33d8e919c7SMasahiro Yamada 	uint32_t tmp;
34d8e919c7SMasahiro Yamada 
35*577b2441SMasahiro Yamada 	mmio_write_32(UNIPHIER_STMBE2COM + 4, scp_base);
36d8e919c7SMasahiro Yamada 	mmio_write_32(UNIPHIER_STMBE2COM, UNIPHIER_SCP_READY_MAGIC);
37d8e919c7SMasahiro Yamada 
38d8e919c7SMasahiro Yamada 	do {
39d8e919c7SMasahiro Yamada 		tmp = mmio_read_32(UNIPHIER_ROM_RSV3);
40d8e919c7SMasahiro Yamada 	} while (!(tmp & BIT(8)));
41d8e919c7SMasahiro Yamada 
42d8e919c7SMasahiro Yamada 	mmio_write_32(UNIPHIER_ROM_RSV3, tmp | BIT(9));
43d8e919c7SMasahiro Yamada }
44d8e919c7SMasahiro Yamada 
uniphier_scp_send_packet(const uint8_t * packet,int packet_len)45d8e919c7SMasahiro Yamada static void uniphier_scp_send_packet(const uint8_t *packet, int packet_len)
46d8e919c7SMasahiro Yamada {
47d8e919c7SMasahiro Yamada 	uintptr_t reg = UNIPHIER_STMBE2COM;
48d8e919c7SMasahiro Yamada 	uint32_t word;
49d8e919c7SMasahiro Yamada 	int len, i;
50d8e919c7SMasahiro Yamada 
51d8e919c7SMasahiro Yamada 	while (packet_len) {
52d8e919c7SMasahiro Yamada 		len = MIN(packet_len, 4);
53d8e919c7SMasahiro Yamada 		word = 0;
54d8e919c7SMasahiro Yamada 
55d8e919c7SMasahiro Yamada 		for (i = 0; i < len; i++)
56d8e919c7SMasahiro Yamada 			word |= *packet++ << (8 * i);
57d8e919c7SMasahiro Yamada 
58d8e919c7SMasahiro Yamada 		mmio_write_32(reg, word);
59d8e919c7SMasahiro Yamada 		reg += 4;
60d8e919c7SMasahiro Yamada 		packet_len -= len;
61d8e919c7SMasahiro Yamada 	}
62d8e919c7SMasahiro Yamada 
63d8e919c7SMasahiro Yamada 	mmio_write_8(UNIPHIER_BETOSTMIRQ0PT, 0x55);
64e6a90288SDai Okamura 
65e6a90288SDai Okamura 	while (!(mmio_read_32(UNIPHIER_STMTOBEIRQ) & BIT(1)))
66e6a90288SDai Okamura 		;
67e6a90288SDai Okamura 	mmio_write_8(UNIPHIER_BEIRQCLRPT, BIT(1) | BIT(0));
68d8e919c7SMasahiro Yamada }
69d8e919c7SMasahiro Yamada 
uniphier_scp_send_cmd(const uint8_t * cmd,int cmd_len)70d8e919c7SMasahiro Yamada static void uniphier_scp_send_cmd(const uint8_t *cmd, int cmd_len)
71d8e919c7SMasahiro Yamada {
72d8e919c7SMasahiro Yamada 	uint8_t packet[32];	/* long enough */
73d8e919c7SMasahiro Yamada 	uint8_t *p = packet;
74d8e919c7SMasahiro Yamada 	uint8_t c;
75d8e919c7SMasahiro Yamada 	int i;
76d8e919c7SMasahiro Yamada 
77d8e919c7SMasahiro Yamada 	*p++ = UNIPHIER_SCP_PACKET_START;
78d8e919c7SMasahiro Yamada 	*p++ = cmd_len;
79d8e919c7SMasahiro Yamada 
80d8e919c7SMasahiro Yamada 	for (i = 0; i < cmd_len; i++) {
81d8e919c7SMasahiro Yamada 		c = *cmd++;
82d8e919c7SMasahiro Yamada 		if (UNIPHIER_SCP_IS_CTRL_CODE(c)) {
83d8e919c7SMasahiro Yamada 			*p++ = UNIPHIER_SCP_PACKET_ESC;
84d8e919c7SMasahiro Yamada 			*p++ = c ^ BIT(7);
85d8e919c7SMasahiro Yamada 		} else {
86d8e919c7SMasahiro Yamada 			*p++ = c;
87d8e919c7SMasahiro Yamada 		}
88d8e919c7SMasahiro Yamada 	}
89d8e919c7SMasahiro Yamada 
90d8e919c7SMasahiro Yamada 	*p++ = UNIPHIER_SCP_PACKET_END;
91d8e919c7SMasahiro Yamada 
92d8e919c7SMasahiro Yamada 	uniphier_scp_send_packet(packet, p - packet);
93d8e919c7SMasahiro Yamada }
94d8e919c7SMasahiro Yamada 
95d8e919c7SMasahiro Yamada #define UNIPHIER_SCP_CMD(name, ...)					\
96d8e919c7SMasahiro Yamada static const uint8_t __uniphier_scp_##name##_cmd[] = {			\
97d8e919c7SMasahiro Yamada 	__VA_ARGS__							\
98d8e919c7SMasahiro Yamada };									\
99d8e919c7SMasahiro Yamada void uniphier_scp_##name(void)						\
100d8e919c7SMasahiro Yamada {									\
101d8e919c7SMasahiro Yamada 	uniphier_scp_send_cmd(__uniphier_scp_##name##_cmd,		\
102d8e919c7SMasahiro Yamada 			      ARRAY_SIZE(__uniphier_scp_##name##_cmd));	\
103d8e919c7SMasahiro Yamada }
104d8e919c7SMasahiro Yamada 
105d8e919c7SMasahiro Yamada UNIPHIER_SCP_CMD(open_com, 0x00, 0x00, 0x05)
106d8e919c7SMasahiro Yamada UNIPHIER_SCP_CMD(system_off, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01)
107d8e919c7SMasahiro Yamada UNIPHIER_SCP_CMD(system_reset, 0x00, 0x02, 0x00)
108