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