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 */ 126typedef 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 */ 138void scmi_get_channel(scmi_channel_t *ch); 139void scmi_send_sync_command(scmi_channel_t *ch); 140void scmi_put_channel(scmi_channel_t *ch); 141 142static 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