1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *      Message Handling Unit (MHU) v3 Device Driver.
9  */
10 
11 #ifndef MOD_MHU3_H
12 #define MOD_MHU3_H
13 
14 #include <fwk_macros.h>
15 
16 #include <stdint.h>
17 
18 #define SCP_MHU3_PBX_MBX_SIZE (64 * 1024)
19 
20 /* Mask to apply to MBX_FCH_CTRL to enable Fast Channel Mailbox interrupts */
21 #define SCP_MHU3_MBX_INT_EN (4U)
22 
23 /*!
24  * \addtogroup GroupModules Modules
25  * \{
26  */
27 
28 /*!
29  * \defgroup GroupMHUv3 Message Handling Unit (MHU) v3 Driver
30  * \{
31  */
32 
33 /*! \brief MHU v3 Channel Types */
34 enum mod_mhu3_channel_type {
35     /*! Doorbell channel type */
36     MOD_MHU3_CHANNEL_TYPE_DBCH,
37     /* Fast channel type */
38     MOD_MHU3_CHANNEL_TYPE_FCH,
39 };
40 
41 /*!
42  * \brief API indices
43  */
44 enum mod_mhu3_api_idx {
45 #ifdef BUILD_HAS_MOD_TRANSPORT
46     /*! TRANSPORT driver API */
47     MOD_MHU3_API_IDX_TRANSPORT_DRIVER,
48 #endif
49     /*! MHU3 API count */
50     MOD_MHU3_API_IDX_COUNT,
51 };
52 
53 /*! \brief Doorbell channel configuration
54  *
55  *  \details   In MHU3 we can have up to 128 doorbell channels and each
56  *      channel can represent 32 independent events indicated
57  *      by a flag within the doorbell register.
58  *      Hence in MHU3 a channel is represented by its MBX and PBX
59  *      number(s) (e.g SCP -> AP) and the position of the event flags
60  */
61 struct mod_mhu3_dbch_config {
62     /*! PBX channel number */
63     uint32_t pbx_channel : 8;
64     /*!
65      * Each doorbell channel has 32 bits which represents
66      * 32 independent 'events' per doorbell channel
67      * flag_pos indicates position of the bit(flag) within doorbell
68      * register on which this channel is expected to send or
69      * receive communication.
70      */
71     uint32_t pbx_flag_pos : 8;
72 
73     /*! MBX channel number */
74     uint32_t mbx_channel : 8;
75     /*! MBX flag position within channel */
76     uint32_t mbx_flag_pos : 8;
77 };
78 
79 /*!
80  * \brief Fast channel direction, Fast Channels are unidirectional
81  */
82 enum mod_fch_direction {
83     /*! Direction in: Channel used by this processor to receive messages */
84     MOD_MHU3_FCH_DIR_IN,
85     /*! Direction out: Channel used by this processor to send messages */
86     MOD_MHU3_FCH_DIR_OUT,
87     /*! Direction count */
88     MOD_MHU3_FCH_DIR_COUNT,
89 };
90 
91 /*! \brief Fast channel configuration
92  *
93  *  \details   In MHU3 the number of Fast Channels that can be supported is
94  *      configurable between:
95  *      * 1-1024 when the Fast Channel word-size is 32 bits.
96  *      * 1-512 when the Fast Channel word-size is 64 bits.
97  *      Due to the possible number of Fast Channels, they are controlled in
98  *      groups called Fast Channel Groups. There can be between 1 and 32 Fast
99  *      Channel Groups in a Postbox or Mailbox each containing between 1 and 32
100  *      Fast Channels.
101  */
102 struct mod_mhu3_fc_config {
103     /*!
104      * Fast Channel idx:
105      * offset of the word in PFCW<n>_PAY
106      * e.g for
107      *     idx 0 is PFCW_PAY + (0 * 4)
108      *     idx 1 is PFCW_PAY + (1 * 4)
109      * grup_num marks the end of the group
110      * e.g.
111      *     for idx 0 & grup_num 2 it
112      *     is PCFW_PAY + (0 * 4) to PCFW_PAY + (0 * 4 + 4 * 2)
113      */
114     uint16_t idx;
115     /*! Fast Channel Group number for the given Fast Channel
116      * There can be between 1-32 Fast Channel Groups.
117      */
118     uint8_t grp_num;
119     /*! Fast Channel Direction */
120     enum mod_fch_direction direction;
121 };
122 
123 /*! \brief Configuration of a channel between MHU(S/R) <=> MHU(R/S)
124  *
125  *  \details Each MHU v3 channel is identified using its type
126  *      e.g. Doorbell channel or Fast Channel (see ::mod_mhu3_channel_type)
127  *      Each channel includes its associated channel information e.g.
128  *      in doorbell channel it will be represented by a PBX channel number, its
129  *      flag position within corresponding PBX channel, MBX channel number and
130  *      its flag position within corresponding MBX channel.
131  */
132 struct mod_mhu3_channel_config {
133     /*! Type of the MHU channel */
134     enum mod_mhu3_channel_type type;
135     /*! Configuration of the specified channel type */
136     union {
137         /*! Doorbell channel configuration */
138         struct mod_mhu3_dbch_config dbch;
139         /*! Fast channel configuration */
140         struct mod_mhu3_fc_config fch;
141     };
142 };
143 
144 /*!
145  * \brief MHU v3 device
146  *
147  * \details Abstract representation of a bidirectional MHU device that consists
148  *      of a single receive interrupt line and channel configuration.
149  */
150 struct mod_mhu3_device_config {
151     /*! IRQ number of the receive interrupt line */
152     unsigned int irq;
153 
154     /*! Base address of the registers of the incoming MHU, MBX
155      * (base address of the paired PBX on the target with current processor)
156      */
157     uintptr_t in;
158 
159     /*! Base address of the registers of the outgoing MHU, PBX
160      * (base address of the paired MBX on the target with current processor)
161      */
162     uintptr_t out;
163 
164     /*! Base address of the registers of the incoming MHU, MBX
165      * (as seen by the firmware/OS running on the target processor)
166      */
167     uintptr_t in_target;
168 
169     /*! Base address of the registers of the outgoing MHU, PBX
170      * (as seen by the firmware/OS running on the target processor)
171      */
172     uintptr_t out_target;
173 
174     /*! Channel configuration array */
175     struct mod_mhu3_channel_config *channels;
176 };
177 
178 /*!
179  * \brief Build an MHU v3 Doorbell channel configuration
180  *
181  * \note This macro expands to a designated channel configuration, and can be
182  *     used to initialize a ::mod_mhu3_channel_config.
183  *
184  * \details Example usage:
185  *      \code{.c}
186  *      struct mod_mhu3_channel_config ch = MOD_MHU3_INIT_DBCH(0, 1, 0, 1)
187  *      \endcode
188  *
189  * \param PBX_CH_NUMBER PostBox channel number.
190  * \param PBX_FLAG_POS PostBox flag position.
191  * \param MBX_CH_NUMBER Mailbox channel number.
192  * \param MBX_FLAG_POS Mailbox flag position.
193  *
194  * \return Element identifier.
195  */
196 #define MOD_MHU3_INIT_DBCH( \
197     PBX_CH_NUMBER, PBX_FLAG_POS, MBX_CH_NUMBER, MBX_FLAG_POS) \
198     { \
199         .type = MOD_MHU3_CHANNEL_TYPE_DBCH, \
200         { \
201             .dbch = { \
202                 .pbx_channel = PBX_CH_NUMBER, \
203                 .pbx_flag_pos = PBX_FLAG_POS, \
204                 .mbx_channel = MBX_CH_NUMBER, \
205                 .mbx_flag_pos = MBX_FLAG_POS, \
206             }, \
207         } \
208     }
209 
210 /*!
211  * \brief Build an MHU v3 Fast channel configuration
212  *
213  * \note This macro expands to a designated fast channel configuration,
214  *     and can be used to initialize a ::mod_mhu3_channel_config.
215  *
216  * \details Example usage:
217  *      \code{.c}
218  *      struct mod_mhu3_channel_config ch = MOD_MHU3_INIT_FCH(0, 1, 0)
219  *      \endcode
220  *
221  * \param FCH_IDX Channel number.
222  * \param FCH_GROUP_NUM Fast Channel Group number for the given Fast Channel.
223  * \param FCH_DIRECTION Fast Channel direction in or out.
224  *
225  * \return Element identifier.
226  */
227 #define MOD_MHU3_INIT_FCH(FCH_IDX, FCH_GROUP_NUM, FCH_DIRECTION) \
228     { \
229         .type = MOD_MHU3_CHANNEL_TYPE_FCH, \
230         { \
231             .fch = { \
232                 .idx = FCH_IDX, \
233                 .grp_num = FCH_GROUP_NUM, \
234                 .direction = FCH_DIRECTION, \
235             }, \
236         } \
237     }
238 
239 /*!
240  * \}
241  */
242 
243 /*!
244  * \}
245  */
246 
247 #endif /* MOD_MHU3_H */
248