Home | History | Annotate | Download | only in scmi
      1 /*
      2  * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
      3  *
      4  * SPDX-License-Identifier: BSD-3-Clause
      5  */
      6 
      7 #ifndef __CSS_SCMI_PRIVATE_H__
      8 #define __CSS_SCMI_PRIVATE_H__
      9 
     10 /*
     11  * SCMI power domain management protocol message and response lengths. It is
     12  * calculated as sum of length in bytes of the message header (4) and payload
     13  * area (the number of bytes of parameters or return values in the payload).
     14  */
     15 #define SCMI_PROTO_VERSION_MSG_LEN		4
     16 #define SCMI_PROTO_VERSION_RESP_LEN		12
     17 
     18 #define SCMI_PROTO_MSG_ATTR_MSG_LEN		8
     19 #define SCMI_PROTO_MSG_ATTR_RESP_LEN		12
     20 
     21 #define SCMI_PWR_STATE_SET_MSG_LEN		16
     22 #define SCMI_PWR_STATE_SET_RESP_LEN		8
     23 
     24 #define SCMI_PWR_STATE_GET_MSG_LEN		8
     25 #define SCMI_PWR_STATE_GET_RESP_LEN		12
     26 
     27 #define SCMI_SYS_PWR_STATE_SET_MSG_LEN		12
     28 #define SCMI_SYS_PWR_STATE_SET_RESP_LEN		8
     29 
     30 #define SCMI_SYS_PWR_STATE_GET_MSG_LEN		4
     31 #define SCMI_SYS_PWR_STATE_GET_RESP_LEN		12
     32 
     33 /* SCMI message header format bit field */
     34 #define SCMI_MSG_ID_SHIFT		0
     35 #define SCMI_MSG_ID_WIDTH		8
     36 #define SCMI_MSG_ID_MASK		((1 << SCMI_MSG_ID_WIDTH) - 1)
     37 
     38 #define SCMI_MSG_TYPE_SHIFT		8
     39 #define SCMI_MSG_TYPE_WIDTH		2
     40 #define SCMI_MSG_TYPE_MASK		((1 << SCMI_MSG_TYPE_WIDTH) - 1)
     41 
     42 #define SCMI_MSG_PROTO_ID_SHIFT		10
     43 #define SCMI_MSG_PROTO_ID_WIDTH		8
     44 #define SCMI_MSG_PROTO_ID_MASK		((1 << SCMI_MSG_PROTO_ID_WIDTH) - 1)
     45 
     46 #define SCMI_MSG_TOKEN_SHIFT		18
     47 #define SCMI_MSG_TOKEN_WIDTH		10
     48 #define SCMI_MSG_TOKEN_MASK		((1 << SCMI_MSG_TOKEN_WIDTH) - 1)
     49 
     50 
     51 /* SCMI mailbox flags */
     52 #define SCMI_FLAG_RESP_POLL	0
     53 #define SCMI_FLAG_RESP_INT	1
     54 
     55 /* SCMI power domain protocol `POWER_STATE_SET` message flags */
     56 #define SCMI_PWR_STATE_SET_FLAG_SYNC	0
     57 #define SCMI_PWR_STATE_SET_FLAG_ASYNC	1
     58 
     59 /*
     60  * Helper macro to create an SCMI message header given protocol, message id
     61  * and token.
     62  */
     63 #define SCMI_MSG_CREATE(protocol, msg_id, token)				\
     64 	((((protocol) & SCMI_MSG_PROTO_ID_MASK) << SCMI_MSG_PROTO_ID_SHIFT) |	\
     65 	(((msg_id) & SCMI_MSG_ID_MASK) << SCMI_MSG_ID_SHIFT) |			\
     66 	(((token) & SCMI_MSG_TOKEN_MASK) << SCMI_MSG_TOKEN_SHIFT))
     67 
     68 /* Helper macro to get the token from a SCMI message header */
     69 #define SCMI_MSG_GET_TOKEN(msg)				\
     70 	(((msg) >> SCMI_MSG_TOKEN_SHIFT) & SCMI_MSG_TOKEN_MASK)
     71 
     72 /* SCMI Channel Status bit fields */
     73 #define SCMI_CH_STATUS_RES0_MASK	0xFFFFFFFE
     74 #define SCMI_CH_STATUS_FREE_SHIFT	0
     75 #define SCMI_CH_STATUS_FREE_WIDTH	1
     76 #define SCMI_CH_STATUS_FREE_MASK	((1 << SCMI_CH_STATUS_FREE_WIDTH) - 1)
     77 
     78 /* Helper macros to check and write the channel status */
     79 #define SCMI_IS_CHANNEL_FREE(status)					\
     80 	(!!(((status) >> SCMI_CH_STATUS_FREE_SHIFT) & SCMI_CH_STATUS_FREE_MASK))
     81 
     82 #define SCMI_MARK_CHANNEL_BUSY(status)	do {				\
     83 		assert(SCMI_IS_CHANNEL_FREE(status));			\
     84 		(status) &= ~(SCMI_CH_STATUS_FREE_MASK <<		\
     85 				SCMI_CH_STATUS_FREE_SHIFT);		\
     86 	} while (0)
     87 
     88 /* Helper macros to copy arguments to the mailbox payload */
     89 #define SCMI_PAYLOAD_ARG1(payld_arr, arg1)				\
     90 		mmio_write_32((uintptr_t)&payld_arr[0], arg1)
     91 
     92 #define SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2)	do {		\
     93 		SCMI_PAYLOAD_ARG1(payld_arr, arg1);			\
     94 		mmio_write_32((uintptr_t)&payld_arr[1], arg2);		\
     95 	} while (0)
     96 
     97 #define SCMI_PAYLOAD_ARG3(payld_arr, arg1, arg2, arg3)	do {		\
     98 		SCMI_PAYLOAD_ARG2(payld_arr, arg1, arg2);		\
     99 		mmio_write_32((uintptr_t)&payld_arr[2], arg3);		\
    100 	} while (0)
    101 
    102 /* Helper macros to read return values from the mailbox payload */
    103 #define SCMI_PAYLOAD_RET_VAL1(payld_arr, val1)				\
    104 		(val1) = mmio_read_32((uintptr_t)&payld_arr[0])
    105 
    106 #define SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2)	do {		\
    107 		SCMI_PAYLOAD_RET_VAL1(payld_arr, val1);			\
    108 		(val2) = mmio_read_32((uintptr_t)&payld_arr[1]);	\
    109 	} while (0)
    110 
    111 #define SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3)	do {	\
    112 		SCMI_PAYLOAD_RET_VAL2(payld_arr, val1, val2);		\
    113 		(val3) = mmio_read_32((uintptr_t)&payld_arr[2]);	\
    114 	} while (0)
    115 
    116 /* Helper macro to ring doorbell */
    117 #define SCMI_RING_DOORBELL(addr, modify_mask, preserve_mask)	do {	\
    118 		uint32_t db = mmio_read_32(addr) & (preserve_mask);	\
    119 		mmio_write_32(addr, db | (modify_mask));		\
    120 	} while (0)
    121 
    122 /*
    123  * Private data structure for representing the mailbox memory layout. Refer
    124  * the SCMI specification for more details.
    125  */
    126 typedef struct mailbox_mem {
    127 	uint32_t res_a; /* Reserved */
    128 	volatile uint32_t status;
    129 	uint64_t res_b; /* Reserved */
    130 	uint32_t flags;
    131 	volatile uint32_t len;
    132 	uint32_t msg_header;
    133 	uint32_t payload[];
    134 } mailbox_mem_t;
    135 
    136 
    137 /* Private APIs for use within SCMI driver */
    138 void scmi_get_channel(scmi_channel_t *ch);
    139 void scmi_send_sync_command(scmi_channel_t *ch);
    140 void scmi_put_channel(scmi_channel_t *ch);
    141 
    142 static inline void validate_scmi_channel(scmi_channel_t *ch)
    143 {
    144 	assert(ch && ch->is_initialized);
    145 	assert(ch->info && ch->info->scmi_mbx_mem);
    146 }
    147 
    148 #endif	/* __CSS_SCMI_PRIVATE_H__ */
    149