1 /*
2  * Copyright (c) 2023 Arm Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * \file mhu_v3_x.h
19  * \brief Driver for ARM Message Handling Unit version 3.0
20  */
21 
22 #ifndef __MHU_V3_X_H__
23 #define __MHU_V3_X_H__
24 
25 #include <stdint.h>
26 #include <stdbool.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /* MHU Architecture Major Revision 3 */
33 #define MHU_MAJOR_REV_V3 (0x2u)
34 /* MHU Architecture Minor Revision 0 */
35 #define MHU_MINOR_REV_3_0 (0x0u)
36 
37 /* MHU Architecture Major Revision offset */
38 #define MHU_ARCH_MAJOR_REV_OFF (0x4u)
39 /* MHU Architecture Major Revision mask */
40 #define MHU_ARCH_MAJOR_REV_MASK (0xfu << MHU_ARCH_MAJOR_REV_OFF)
41 
42 /* MHU Architecture Minor Revision offset */
43 #define MHU_ARCH_MINOR_REV_OFF (0x0u)
44 /* MHU Architecture Minor Revision mask */
45 #define MHU_ARCH_MINOR_REV_MASK (0xfu << MHU_ARCH_MINOR_REV_OFF)
46 
47 /* MHUv3 PBX/MBX Operational Request offset */
48 #define MHU_V3_OP_REQ_OFF (0u)
49 /* MHUv3 PBX/MBX Operational Request */
50 #define MHU_V3_OP_REQ (1u << MHU_V3_OP_REQ_OFF)
51 
52 /**
53  * \brief MHUv3 error enumeration types
54  */
55 enum mhu_v3_x_error_t {
56     /* No error */
57     MHU_V_3_X_ERR_NONE,
58     /* MHU driver not initialized */
59     MHU_V_3_X_ERR_NOT_INIT,
60     /* MHU Revision not supported error */
61     MHU_V_3_X_ERR_UNSUPPORTED_VERSION,
62     /* Operation not supported */
63     MHU_V_3_X_ERR_UNSUPPORTED,
64     /* Invalid parameter */
65     MHU_V_3_X_ERR_INVALID_PARAM,
66     /* General MHU driver error */
67     MHU_V_3_X_ERR_GENERAL,
68 };
69 
70 /**
71  * \brief MHUv3 channel types
72  */
73 enum mhu_v3_x_channel_type_t {
74     /* Doorbell channel */
75     MHU_V3_X_CHANNEL_TYPE_DBCH,
76     /* Channel type count */
77     MHU_V3_X_CHANNEL_TYPE_COUNT,
78 };
79 
80 /**
81  * \brief MHUv3 frame types
82  */
83 enum mhu_v3_x_frame_t {
84     /* MHUv3 postbox frame */
85     MHU_V3_X_PBX_FRAME,
86     /* MHUv3 mailbox frame */
87     MHU_V3_X_MBX_FRAME,
88 };
89 
90 /**
91  * \brief MHUv3 device structure
92  */
93 struct mhu_v3_x_dev_t {
94     /* Base address of the MHUv3 frame */
95     const uintptr_t base;
96     /* Type of the MHUv3 frame */
97     enum mhu_v3_x_frame_t frame;
98     /* Minor revision of the MHUv3 */
99     uint32_t subversion;
100     /* Flag to indicate if the MHUv3 is initialized */
101     bool is_initialized;
102 };
103 
104 /**
105  * \brief Initializes the MHUv3
106  *
107  * \param[in] dev    MHU device struct \ref mhu_v3_x_dev_t
108  *
109  * \return Returns error code as specified in \ref mhu_v3_x_error_t
110  */
111 enum mhu_v3_x_error_t mhu_v3_x_driver_init(struct mhu_v3_x_dev_t *dev);
112 
113 /**
114  * \brief Returns the number of channels implemented
115  *
116  * \param[in]  dev        MHU device struct \ref mhu_v3_x_dev_t
117  * \param[in]  ch_type    MHU channel type \ref mhu_v3_x_channel_type_t
118  * \param[out] num_ch     Pointer to the variable that will store the value
119  *
120  * \return Returns error code as specified in \ref mhu_v3_x_error_t
121  */
122 enum mhu_v3_x_error_t mhu_v3_x_get_num_channel_implemented(
123      const struct mhu_v3_x_dev_t *dev,
124      enum mhu_v3_x_channel_type_t ch_type, uint8_t *num_ch);
125 
126 /**
127  * \brief Clears the doorbell channel
128  *
129  * \param[in] dev        MHU device struct \ref mhu_v3_x_dev_t
130  * \param[in] channel    Channel number
131  * \param[in] mask       Mask to be used when clearing the channel
132  *
133  * \return Returns error code as specified in \ref mhu_v3_x_error_t
134  */
135 enum mhu_v3_x_error_t mhu_v3_x_doorbell_clear(struct mhu_v3_x_dev_t *dev,
136      uint32_t channel, uint32_t mask);
137 
138 /**
139  * \brief Write value to a doorbell channel
140  *
141  * \param[in] dev        MHU device struct \ref mhu_v3_x_dev_t
142  * \param[in] channel    Doorbell channel number
143  * \param[in] value      Value to be written to the channel
144  *
145  * \return Returns error code as specified in \ref mhu_v3_x_error_t
146  */
147 enum mhu_v3_x_error_t mhu_v3_x_doorbell_write(struct mhu_v3_x_dev_t *dev,
148      uint32_t channel, uint32_t value);
149 
150 /**
151  * \brief Read value from a doorbell channel
152  *
153  * \param[in]  dev        MHU device struct \ref mhu_v3_x_dev_t
154  * \param[in]  channel    Doorbell channel number
155  * \param[out] value      Pointer to the variable that will store the value
156  *
157  * \return Returns error code as specified in \ref mhu_v3_x_error_t
158  */
159 enum mhu_v3_x_error_t mhu_v3_x_doorbell_read(struct mhu_v3_x_dev_t *dev,
160      uint32_t channel, uint32_t *value);
161 
162 /**
163  * \brief Set bits in a doorbell channel mask
164  *
165  * \param[in] dev        MHU device struct \ref mhu_v3_x_dev_t
166  * \param[in] channel    Doorbell channel number
167  * \param[in] mask       Mask to be set over the doorbell channel
168  *
169  * \return Returns error code as specified in \ref mhu_v3_x_error_t
170  */
171 enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_set(
172      struct mhu_v3_x_dev_t *dev, uint32_t channel, uint32_t mask);
173 
174 /**
175  * \brief Clear bits in a doorbell channel mask
176  *
177  * \param[in] dev        MHU device struct \ref mhu_v3_x_dev_t
178  * \param[in] channel    Doorbell channel number
179  * \param[in] mask       Mask to be cleared over the doorbell channel
180  *
181  * \return Returns error code as specified in \ref mhu_v3_x_error_t
182  */
183 enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_clear(
184      struct mhu_v3_x_dev_t *dev, uint32_t channel, uint32_t mask);
185 
186 /**
187  * \brief Get the mask of a doorbell channel
188  *
189  * \param[in]  dev            MHU device struct \ref mhu_v3_x_dev_t
190  * \param[in]  channel        Doorbell channel number
191  * \param[out] mask_status    Pointer to the variable that will store the value
192  *
193  * \return Returns error code as specified in \ref mhu_v3_x_error_t
194  */
195 enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_get(
196      struct mhu_v3_x_dev_t *dev, uint32_t channel, uint32_t *mask_status);
197 
198 /**
199  * \brief Enable the channel interrupt
200  *
201  * \param[in]  dev        MHU device struct \ref mhu_v3_x_dev_t
202  * \param[in]  channel    Channel number
203  * \param[in]  ch_type    MHU channel type \ref mhu_v3_x_channel_type_t
204  *
205  * \return Returns error code as specified in \ref mhu_v3_x_error_t
206  */
207 enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_enable(
208      struct mhu_v3_x_dev_t *dev, uint32_t channel,
209      enum mhu_v3_x_channel_type_t ch_type);
210 
211 /**
212  * \brief Disable the channel interrupt
213  *
214  * \param[in]  dev        MHU device struct \ref mhu_v3_x_dev_t
215  * \param[in]  channel    Channel number
216  * \param[in]  ch_type    MHU channel type \ref mhu_v3_x_channel_type_t
217  *
218  * \return Returns error code as specified in \ref mhu_v3_x_error_t
219  */
220 enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_disable(
221      struct mhu_v3_x_dev_t *dev, uint32_t channel,
222      enum mhu_v3_x_channel_type_t ch_type);
223 
224 /**
225  * \brief Clear the channel interrupt
226  *
227  * \param[in]  dev        MHU device struct \ref mhu_v3_x_dev_t
228  * \param[in]  channel    Channel number
229  * \param[in]  ch_type    MHU channel type \ref mhu_v3_x_channel_type_t
230  *
231  * \return Returns error code as specified in \ref mhu_v3_x_error_t
232  */
233 enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_clear(
234      struct mhu_v3_x_dev_t *dev, uint32_t channel,
235      enum mhu_v3_x_channel_type_t ch_type);
236 
237 #ifdef __cplusplus
238 }
239 #endif
240 
241 #endif /* __MHU_V3_X_H__ */
242