scmi_private.h 4.82 KB
Newer Older
Soby Mathew's avatar
Soby Mathew committed
1
/*
2
 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
Soby Mathew's avatar
Soby Mathew committed
3
4
5
6
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

7
8
#ifndef SCMI_PRIVATE_H
#define SCMI_PRIVATE_H
Soby Mathew's avatar
Soby Mathew committed
9

10
11
#include <lib/mmio.h>

Soby Mathew's avatar
Soby Mathew committed
12
13
14
15
16
17
18
19
20
21
22
/*
 * SCMI power domain management protocol message and response lengths. It is
 * calculated as sum of length in bytes of the message header (4) and payload
 * area (the number of bytes of parameters or return values in the payload).
 */
#define SCMI_PROTO_VERSION_MSG_LEN		4
#define SCMI_PROTO_VERSION_RESP_LEN		12

#define SCMI_PROTO_MSG_ATTR_MSG_LEN		8
#define SCMI_PROTO_MSG_ATTR_RESP_LEN		12

23
24
25
26
27
28
#define SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN	16
#define SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN	8

#define SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN	4
#define SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN	20

Soby Mathew's avatar
Soby Mathew committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#define SCMI_PWR_STATE_SET_MSG_LEN		16
#define SCMI_PWR_STATE_SET_RESP_LEN		8

#define SCMI_PWR_STATE_GET_MSG_LEN		8
#define SCMI_PWR_STATE_GET_RESP_LEN		12

#define SCMI_SYS_PWR_STATE_SET_MSG_LEN		12
#define SCMI_SYS_PWR_STATE_SET_RESP_LEN		8

#define SCMI_SYS_PWR_STATE_GET_MSG_LEN		4
#define SCMI_SYS_PWR_STATE_GET_RESP_LEN		12

/* SCMI message header format bit field */
#define SCMI_MSG_ID_SHIFT		0
#define SCMI_MSG_ID_WIDTH		8
#define SCMI_MSG_ID_MASK		((1 << SCMI_MSG_ID_WIDTH) - 1)

#define SCMI_MSG_TYPE_SHIFT		8
#define SCMI_MSG_TYPE_WIDTH		2
#define SCMI_MSG_TYPE_MASK		((1 << SCMI_MSG_TYPE_WIDTH) - 1)

#define SCMI_MSG_PROTO_ID_SHIFT		10
#define SCMI_MSG_PROTO_ID_WIDTH		8
#define SCMI_MSG_PROTO_ID_MASK		((1 << SCMI_MSG_PROTO_ID_WIDTH) - 1)

#define SCMI_MSG_TOKEN_SHIFT		18
#define SCMI_MSG_TOKEN_WIDTH		10
#define SCMI_MSG_TOKEN_MASK		((1 << SCMI_MSG_TOKEN_WIDTH) - 1)


/* SCMI mailbox flags */
#define SCMI_FLAG_RESP_POLL	0
#define SCMI_FLAG_RESP_INT	1

/* SCMI power domain protocol `POWER_STATE_SET` message flags */
#define SCMI_PWR_STATE_SET_FLAG_SYNC	0
#define SCMI_PWR_STATE_SET_FLAG_ASYNC	1

/*
 * Helper macro to create an SCMI message header given protocol, message id
 * and token.
 */
Daniel Boulby's avatar
Daniel Boulby committed
71
72
73
74
#define SCMI_MSG_CREATE(_protocol, _msg_id, _token)				\
	((((_protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) |	\
	(((_msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) |			\
	(((_token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT))
Soby Mathew's avatar
Soby Mathew committed
75
76

/* Helper macro to get the token from a SCMI message header */
Daniel Boulby's avatar
Daniel Boulby committed
77
78
#define SCMI_MSG_GET_TOKEN(_msg)				\
	(((_msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK)
Soby Mathew's avatar
Soby Mathew committed
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

/* SCMI Channel Status bit fields */
#define SCMI_CH_STATUS_RES0_MASK	0xFFFFFFFE
#define SCMI_CH_STATUS_FREE_SHIFT	0
#define SCMI_CH_STATUS_FREE_WIDTH	1
#define SCMI_CH_STATUS_FREE_MASK	((1 << SCMI_CH_STATUS_FREE_WIDTH) - 1)

/* Helper macros to check and write the channel status */
#define SCMI_IS_CHANNEL_FREE(status)					\
	(!!(((status) >> SCMI_CH_STATUS_FREE_SHIFT) & SCMI_CH_STATUS_FREE_MASK))

#define SCMI_MARK_CHANNEL_BUSY(status)	do {				\
		assert(SCMI_IS_CHANNEL_FREE(status));			\
		(status) &= ~(SCMI_CH_STATUS_FREE_MASK <<		\
				SCMI_CH_STATUS_FREE_SHIFT);		\
	} while (0)

/* Helper macros to copy arguments to the mailbox payload */
#define SCMI_PAYLOAD_ARG1(payld_arr, arg1)				\
		mmio_write_32((uintptr_t)&payld_arr[0], arg1)

#define SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2)	do {		\
		SCMI_PAYLOAD_ARG1(payld_arr, arg1);			\
		mmio_write_32((uintptr_t)&payld_arr[1], arg2);		\
	} while (0)

#define SCMI_PAYLOAD_ARG3(payld_arr, arg1, arg2, arg3)	do {		\
		SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2);		\
		mmio_write_32((uintptr_t)&payld_arr[2], arg3);		\
	} while (0)

/* Helper macros to read return values from the mailbox payload */
#define SCMI_PAYLOAD_RET_VAL1(payld_arr, val1)				\
		(val1) = mmio_read_32((uintptr_t)&payld_arr[0])

#define SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2)	do {		\
		SCMI_PAYLOAD_RET_VAL1(payld_arr, val1);			\
		(val2) = mmio_read_32((uintptr_t)&payld_arr[1]);	\
	} while (0)

#define SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3)	do {	\
		SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2);		\
		(val3) = mmio_read_32((uintptr_t)&payld_arr[2]);	\
	} while (0)

124
125
126
127
128
#define SCMI_PAYLOAD_RET_VAL4(payld_arr, val1, val2, val3, val4)	do {	\
		SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3);		\
		(val4) = mmio_read_32((uintptr_t)&payld_arr[3]);		\
	} while (0)

Soby Mathew's avatar
Soby Mathew committed
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * Private data structure for representing the mailbox memory layout. Refer
 * the SCMI specification for more details.
 */
typedef struct mailbox_mem {
	uint32_t res_a; /* Reserved */
	volatile uint32_t status;
	uint64_t res_b; /* Reserved */
	uint32_t flags;
	volatile uint32_t len;
	uint32_t msg_header;
	uint32_t payload[];
} mailbox_mem_t;


/* Private APIs for use within SCMI driver */
void scmi_get_channel(scmi_channel_t *ch);
void scmi_send_sync_command(scmi_channel_t *ch);
void scmi_put_channel(scmi_channel_t *ch);

static inline void validate_scmi_channel(scmi_channel_t *ch)
{
	assert(ch && ch->is_initialized);
	assert(ch->info && ch->info->scmi_mbx_mem);
}

155
#endif /* SCMI_PRIVATE_H */