1bc174764SAziz IDOMAR /*
2bc174764SAziz IDOMAR * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
3bc174764SAziz IDOMAR *
4bc174764SAziz IDOMAR * SPDX-License-Identifier: BSD-3-Clause
5bc174764SAziz IDOMAR */
6bc174764SAziz IDOMAR
7bc174764SAziz IDOMAR #include <assert.h>
8bc174764SAziz IDOMAR #include <stdbool.h>
9bc174764SAziz IDOMAR #include <stdint.h>
10bc174764SAziz IDOMAR
11bc174764SAziz IDOMAR #include "mhu_v3_x.h"
12bc174764SAziz IDOMAR
13bc174764SAziz IDOMAR #include "mhu_v3_x_private.h"
14bc174764SAziz IDOMAR
15bc174764SAziz IDOMAR /*
16bc174764SAziz IDOMAR * Get the device base from the device struct. Return an error if the dev is
17bc174764SAziz IDOMAR * invalid.
18bc174764SAziz IDOMAR */
get_dev_base(const struct mhu_v3_x_dev_t * dev,union _mhu_v3_x_frame_t ** base)19bc174764SAziz IDOMAR static enum mhu_v3_x_error_t get_dev_base(const struct mhu_v3_x_dev_t *dev,
20bc174764SAziz IDOMAR union _mhu_v3_x_frame_t **base)
21bc174764SAziz IDOMAR {
22bc174764SAziz IDOMAR if (dev == NULL) {
23bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
24bc174764SAziz IDOMAR }
25bc174764SAziz IDOMAR
26bc174764SAziz IDOMAR /* Ensure driver has been initialized */
27bc174764SAziz IDOMAR if (dev->is_initialized == false) {
28bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NOT_INIT;
29bc174764SAziz IDOMAR }
30bc174764SAziz IDOMAR
31bc174764SAziz IDOMAR *base = (union _mhu_v3_x_frame_t *)dev->base;
32bc174764SAziz IDOMAR
33bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
34bc174764SAziz IDOMAR }
35bc174764SAziz IDOMAR
mhu_v3_x_driver_init(struct mhu_v3_x_dev_t * dev)36bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_driver_init(struct mhu_v3_x_dev_t *dev)
37bc174764SAziz IDOMAR {
38bc174764SAziz IDOMAR uint32_t aidr = 0;
39bc174764SAziz IDOMAR uint8_t mhu_major_rev;
40bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
41bc174764SAziz IDOMAR
42bc174764SAziz IDOMAR if (dev == NULL) {
43bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
44bc174764SAziz IDOMAR }
45bc174764SAziz IDOMAR
46bc174764SAziz IDOMAR /* Return if already initialized */
47bc174764SAziz IDOMAR if (dev->is_initialized == true) {
48bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
49bc174764SAziz IDOMAR }
50bc174764SAziz IDOMAR
51bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
52bc174764SAziz IDOMAR
53bc174764SAziz IDOMAR /* Read revision from MHU hardware */
54bc174764SAziz IDOMAR if (dev->frame == MHU_V3_X_PBX_FRAME) {
55bc174764SAziz IDOMAR aidr = p_mhu->pbx_frame.pbx_ctrl_page.pbx_aidr;
56bc174764SAziz IDOMAR } else if (dev->frame == MHU_V3_X_MBX_FRAME) {
57bc174764SAziz IDOMAR aidr = p_mhu->mbx_frame.mbx_ctrl_page.mbx_aidr;
58bc174764SAziz IDOMAR } else {
59bc174764SAziz IDOMAR /* Only PBX and MBX frames are supported. */
60bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
61bc174764SAziz IDOMAR }
62bc174764SAziz IDOMAR
63bc174764SAziz IDOMAR /* Read the MHU Architecture Major Revision */
64bc174764SAziz IDOMAR mhu_major_rev =
65bc174764SAziz IDOMAR ((aidr & MHU_ARCH_MAJOR_REV_MASK) >> MHU_ARCH_MAJOR_REV_OFF);
66bc174764SAziz IDOMAR
67bc174764SAziz IDOMAR /* Return error if the MHU major revision is not 3 */
68bc174764SAziz IDOMAR if (mhu_major_rev != MHU_MAJOR_REV_V3) {
69bc174764SAziz IDOMAR /* Unsupported MHU version */
70bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED_VERSION;
71bc174764SAziz IDOMAR }
72bc174764SAziz IDOMAR
73bc174764SAziz IDOMAR /* Read the MHU Architecture Minor Revision */
74bc174764SAziz IDOMAR dev->subversion =
75*9fad664eSOlivier Deprez ((aidr & MHU_ARCH_MINOR_REV_MASK) >> MHU_ARCH_MINOR_REV_OFF);
76bc174764SAziz IDOMAR
77bc174764SAziz IDOMAR /* Return error if the MHU minor revision is not 0 */
78bc174764SAziz IDOMAR if (dev->subversion != MHU_MINOR_REV_3_0) {
79bc174764SAziz IDOMAR /* Unsupported subversion */
80bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED_VERSION;
81bc174764SAziz IDOMAR }
82bc174764SAziz IDOMAR
83bc174764SAziz IDOMAR /* Initialize the Postbox/Mailbox to remain in operational state */
84bc174764SAziz IDOMAR if (dev->frame == MHU_V3_X_PBX_FRAME) {
85bc174764SAziz IDOMAR p_mhu->pbx_frame.pbx_ctrl_page.pbx_ctrl |= MHU_V3_OP_REQ;
86bc174764SAziz IDOMAR } else if (dev->frame == MHU_V3_X_MBX_FRAME) {
87bc174764SAziz IDOMAR p_mhu->mbx_frame.mbx_ctrl_page.mbx_ctrl |= MHU_V3_OP_REQ;
88bc174764SAziz IDOMAR } else {
89bc174764SAziz IDOMAR /* Only PBX and MBX frames are supported. */
90bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
91bc174764SAziz IDOMAR }
92bc174764SAziz IDOMAR
93bc174764SAziz IDOMAR dev->is_initialized = true;
94bc174764SAziz IDOMAR
95bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
96bc174764SAziz IDOMAR }
97bc174764SAziz IDOMAR
mhu_v3_x_get_num_channel_implemented(const struct mhu_v3_x_dev_t * dev,enum mhu_v3_x_channel_type_t ch_type,uint8_t * num_ch)98bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_get_num_channel_implemented(
99bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev,
100bc174764SAziz IDOMAR enum mhu_v3_x_channel_type_t ch_type, uint8_t *num_ch)
101bc174764SAziz IDOMAR {
102bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
103bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
104bc174764SAziz IDOMAR
105bc174764SAziz IDOMAR if (num_ch == NULL) {
106bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
107bc174764SAziz IDOMAR }
108bc174764SAziz IDOMAR
109bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
110bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
111bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
112bc174764SAziz IDOMAR return status;
113bc174764SAziz IDOMAR }
114bc174764SAziz IDOMAR
115bc174764SAziz IDOMAR /* Only doorbell channel is supported */
116bc174764SAziz IDOMAR if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
117bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
118bc174764SAziz IDOMAR }
119bc174764SAziz IDOMAR
120bc174764SAziz IDOMAR /* Read the number of channels implemented in the MHU */
121bc174764SAziz IDOMAR if (dev->frame == MHU_V3_X_PBX_FRAME) {
122bc174764SAziz IDOMAR *num_ch = (p_mhu->pbx_frame.pbx_ctrl_page.pbx_dbch_cfg0 + 1);
123bc174764SAziz IDOMAR } else if (dev->frame == MHU_V3_X_MBX_FRAME) {
124bc174764SAziz IDOMAR *num_ch = (p_mhu->mbx_frame.mbx_ctrl_page.mbx_dbch_cfg0 + 1);
125bc174764SAziz IDOMAR } else {
126bc174764SAziz IDOMAR /* Only PBX and MBX frames are supported. */
127bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
128bc174764SAziz IDOMAR }
129bc174764SAziz IDOMAR
130bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
131bc174764SAziz IDOMAR }
132bc174764SAziz IDOMAR
mhu_v3_x_doorbell_clear(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,uint32_t flags)133bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_doorbell_clear(const struct mhu_v3_x_dev_t *dev,
134bc174764SAziz IDOMAR const uint32_t channel, uint32_t flags)
135bc174764SAziz IDOMAR {
136bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
137bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
138bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
139bc174764SAziz IDOMAR
140bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
141bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
142bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
143bc174764SAziz IDOMAR return status;
144bc174764SAziz IDOMAR }
145bc174764SAziz IDOMAR
146bc174764SAziz IDOMAR /* Only MBX can clear the Doorbell channel */
147bc174764SAziz IDOMAR if (dev->frame != MHU_V3_X_MBX_FRAME) {
148bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
149bc174764SAziz IDOMAR }
150bc174764SAziz IDOMAR
151bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
152bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
153bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
154bc174764SAziz IDOMAR
155bc174764SAziz IDOMAR /* Clear the bits in the doorbell channel */
156bc174764SAziz IDOMAR mdbcw_reg[channel].mdbcw_clr |= flags;
157bc174764SAziz IDOMAR
158bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
159bc174764SAziz IDOMAR }
160bc174764SAziz IDOMAR
mhu_v3_x_doorbell_write(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,uint32_t flags)161bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_doorbell_write(const struct mhu_v3_x_dev_t *dev,
162bc174764SAziz IDOMAR const uint32_t channel, uint32_t flags)
163bc174764SAziz IDOMAR {
164bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
165bc174764SAziz IDOMAR struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
166bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
167bc174764SAziz IDOMAR
168bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
169bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
170bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
171bc174764SAziz IDOMAR return status;
172bc174764SAziz IDOMAR }
173bc174764SAziz IDOMAR
174bc174764SAziz IDOMAR /* Only PBX can set the Doorbell channel value */
175bc174764SAziz IDOMAR if (dev->frame != MHU_V3_X_PBX_FRAME) {
176bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
177bc174764SAziz IDOMAR }
178bc174764SAziz IDOMAR
179bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
180bc174764SAziz IDOMAR
181bc174764SAziz IDOMAR pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
182bc174764SAziz IDOMAR &(p_mhu->pbx_frame.pdbcw_page);
183bc174764SAziz IDOMAR
184bc174764SAziz IDOMAR /* Write the value to the doorbell channel */
185bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_set |= flags;
186bc174764SAziz IDOMAR
187bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
188bc174764SAziz IDOMAR }
189bc174764SAziz IDOMAR
mhu_v3_x_doorbell_read(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,uint32_t * flags)190bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_doorbell_read(const struct mhu_v3_x_dev_t *dev,
191bc174764SAziz IDOMAR const uint32_t channel, uint32_t *flags)
192bc174764SAziz IDOMAR {
193bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
194bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
195bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
196bc174764SAziz IDOMAR struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
197bc174764SAziz IDOMAR
198bc174764SAziz IDOMAR if (flags == NULL) {
199bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
200bc174764SAziz IDOMAR }
201bc174764SAziz IDOMAR
202bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
203bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
204bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
205bc174764SAziz IDOMAR return status;
206bc174764SAziz IDOMAR }
207bc174764SAziz IDOMAR
208bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
209bc174764SAziz IDOMAR
210bc174764SAziz IDOMAR if (dev->frame == MHU_V3_X_PBX_FRAME) {
211bc174764SAziz IDOMAR pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
212bc174764SAziz IDOMAR &(p_mhu->pbx_frame.pdbcw_page);
213bc174764SAziz IDOMAR
214bc174764SAziz IDOMAR /* Read the value from Postbox Doorbell status register */
215bc174764SAziz IDOMAR *flags = pdbcw_reg[channel].pdbcw_st;
216bc174764SAziz IDOMAR } else if (dev->frame == MHU_V3_X_MBX_FRAME) {
217bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
218bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
219bc174764SAziz IDOMAR
220bc174764SAziz IDOMAR /* Read the value from Mailbox Doorbell status register */
221bc174764SAziz IDOMAR *flags = mdbcw_reg[channel].mdbcw_st;
222bc174764SAziz IDOMAR } else {
223bc174764SAziz IDOMAR /* Only PBX and MBX frames are supported. */
224bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
225bc174764SAziz IDOMAR }
226bc174764SAziz IDOMAR
227bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
228bc174764SAziz IDOMAR }
229bc174764SAziz IDOMAR
mhu_v3_x_doorbell_mask_set(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,uint32_t flags)230bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_set(
231bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
232bc174764SAziz IDOMAR uint32_t flags)
233bc174764SAziz IDOMAR {
234bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
235bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
236bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
237bc174764SAziz IDOMAR
238bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
239bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
240bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
241bc174764SAziz IDOMAR return status;
242bc174764SAziz IDOMAR }
243bc174764SAziz IDOMAR
244bc174764SAziz IDOMAR /* Doorbell channel mask is not applicable for PBX */
245bc174764SAziz IDOMAR if (dev->frame != MHU_V3_X_MBX_FRAME) {
246bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
247bc174764SAziz IDOMAR }
248bc174764SAziz IDOMAR
249bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
250bc174764SAziz IDOMAR
251bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
252bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
253bc174764SAziz IDOMAR
254bc174764SAziz IDOMAR /* Set the Doorbell channel mask */
255bc174764SAziz IDOMAR mdbcw_reg[channel].mdbcw_msk_set |= flags;
256bc174764SAziz IDOMAR
257bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
258bc174764SAziz IDOMAR }
259bc174764SAziz IDOMAR
mhu_v3_x_doorbell_mask_clear(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,uint32_t flags)260bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_clear(
261bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
262bc174764SAziz IDOMAR uint32_t flags)
263bc174764SAziz IDOMAR {
264bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
265bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
266bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
267bc174764SAziz IDOMAR
268bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
269bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
270bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
271bc174764SAziz IDOMAR return status;
272bc174764SAziz IDOMAR }
273bc174764SAziz IDOMAR
274bc174764SAziz IDOMAR /* Doorbell channel mask is not applicable for PBX */
275bc174764SAziz IDOMAR if (dev->frame != MHU_V3_X_MBX_FRAME) {
276bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
277bc174764SAziz IDOMAR }
278bc174764SAziz IDOMAR
279bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
280bc174764SAziz IDOMAR
281bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
282bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
283bc174764SAziz IDOMAR
284bc174764SAziz IDOMAR /* Clear the Doorbell channel mask */
285bc174764SAziz IDOMAR mdbcw_reg[channel].mdbcw_msk_clr = flags;
286bc174764SAziz IDOMAR
287bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
288bc174764SAziz IDOMAR }
289bc174764SAziz IDOMAR
mhu_v3_x_doorbell_mask_get(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,uint32_t * flags)290bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_doorbell_mask_get(
291bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
292bc174764SAziz IDOMAR uint32_t *flags)
293bc174764SAziz IDOMAR {
294bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
295bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
296bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
297bc174764SAziz IDOMAR
298bc174764SAziz IDOMAR if (flags == NULL) {
299bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
300bc174764SAziz IDOMAR }
301bc174764SAziz IDOMAR
302bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
303bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
304bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
305bc174764SAziz IDOMAR return status;
306bc174764SAziz IDOMAR }
307bc174764SAziz IDOMAR
308bc174764SAziz IDOMAR /* Doorbell channel mask is not applicable for PBX */
309bc174764SAziz IDOMAR if (dev->frame != MHU_V3_X_MBX_FRAME) {
310bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
311bc174764SAziz IDOMAR }
312bc174764SAziz IDOMAR
313bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
314bc174764SAziz IDOMAR
315bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
316bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
317bc174764SAziz IDOMAR
318bc174764SAziz IDOMAR /* Save the Doorbell channel mask status */
319bc174764SAziz IDOMAR *flags = mdbcw_reg[channel].mdbcw_msk_st;
320bc174764SAziz IDOMAR
321bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
322bc174764SAziz IDOMAR }
323bc174764SAziz IDOMAR
mhu_v3_x_channel_interrupt_enable(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,enum mhu_v3_x_channel_type_t ch_type)324bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_enable(
325bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
326bc174764SAziz IDOMAR enum mhu_v3_x_channel_type_t ch_type)
327bc174764SAziz IDOMAR {
328bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
329bc174764SAziz IDOMAR
330bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
331bc174764SAziz IDOMAR struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
332bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
333bc174764SAziz IDOMAR
334bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
335bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
336bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
337bc174764SAziz IDOMAR return status;
338bc174764SAziz IDOMAR }
339bc174764SAziz IDOMAR
340bc174764SAziz IDOMAR /* Only doorbell channel is supported */
341bc174764SAziz IDOMAR if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
342bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
343bc174764SAziz IDOMAR }
344bc174764SAziz IDOMAR
345bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
346bc174764SAziz IDOMAR
347bc174764SAziz IDOMAR if (dev->frame == MHU_V3_X_PBX_FRAME) {
348bc174764SAziz IDOMAR pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
349bc174764SAziz IDOMAR &(p_mhu->pbx_frame.pdbcw_page);
350bc174764SAziz IDOMAR
351bc174764SAziz IDOMAR /*
352bc174764SAziz IDOMAR * Enable this doorbell channel to generate interrupts for
353bc174764SAziz IDOMAR * transfer acknowledge events.
354bc174764SAziz IDOMAR */
355bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_int_en = MHU_V3_X_PDBCW_INT_X_TFR_ACK;
356bc174764SAziz IDOMAR
357bc174764SAziz IDOMAR /*
358bc174764SAziz IDOMAR * Enable this doorbell channel to contribute to the PBX
359bc174764SAziz IDOMAR * combined interrupt.
360bc174764SAziz IDOMAR */
361bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_ctrl = MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN;
362bc174764SAziz IDOMAR } else if (dev->frame == MHU_V3_X_MBX_FRAME) {
363bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
364bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
365bc174764SAziz IDOMAR
366bc174764SAziz IDOMAR /*
367bc174764SAziz IDOMAR * Enable this doorbell channel to contribute to the MBX
368bc174764SAziz IDOMAR * combined interrupt.
369bc174764SAziz IDOMAR */
370bc174764SAziz IDOMAR mdbcw_reg[channel].mdbcw_ctrl = MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN;
371bc174764SAziz IDOMAR } else {
372bc174764SAziz IDOMAR /* Only PBX and MBX frames are supported. */
373bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
374bc174764SAziz IDOMAR }
375bc174764SAziz IDOMAR
376bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
377bc174764SAziz IDOMAR }
378bc174764SAziz IDOMAR
mhu_v3_x_channel_interrupt_disable(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,enum mhu_v3_x_channel_type_t ch_type)379bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_disable(
380bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
381bc174764SAziz IDOMAR enum mhu_v3_x_channel_type_t ch_type)
382bc174764SAziz IDOMAR {
383bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
384bc174764SAziz IDOMAR
385bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
386bc174764SAziz IDOMAR struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
387bc174764SAziz IDOMAR struct _mhu_v3_x_mdbcw_reg_t *mdbcw_reg;
388bc174764SAziz IDOMAR
389bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
390bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
391bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
392bc174764SAziz IDOMAR return status;
393bc174764SAziz IDOMAR }
394bc174764SAziz IDOMAR
395bc174764SAziz IDOMAR /* Only doorbell channel is supported */
396bc174764SAziz IDOMAR if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
397bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
398bc174764SAziz IDOMAR }
399bc174764SAziz IDOMAR
400bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
401bc174764SAziz IDOMAR
402bc174764SAziz IDOMAR if (dev->frame == MHU_V3_X_PBX_FRAME) {
403bc174764SAziz IDOMAR pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)
404bc174764SAziz IDOMAR &(p_mhu->pbx_frame.pdbcw_page);
405bc174764SAziz IDOMAR
406bc174764SAziz IDOMAR /* Clear channel transfer acknowledge event interrupt */
407bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_int_clr = MHU_V3_X_PDBCW_INT_X_TFR_ACK;
408bc174764SAziz IDOMAR
409bc174764SAziz IDOMAR /* Disable channel transfer acknowledge event interrupt */
410bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_int_en &=
411bc174764SAziz IDOMAR ~(MHU_V3_X_PDBCW_INT_X_TFR_ACK);
412bc174764SAziz IDOMAR
413bc174764SAziz IDOMAR /*
414bc174764SAziz IDOMAR * Disable this doorbell channel from contributing to the PBX
415bc174764SAziz IDOMAR * combined interrupt.
416bc174764SAziz IDOMAR */
417bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_ctrl &=
418bc174764SAziz IDOMAR ~(MHU_V3_X_PDBCW_CTRL_PBX_COMB_EN);
419bc174764SAziz IDOMAR } else if (dev->frame == MHU_V3_X_MBX_FRAME) {
420bc174764SAziz IDOMAR mdbcw_reg = (struct _mhu_v3_x_mdbcw_reg_t *)
421bc174764SAziz IDOMAR &(p_mhu->mbx_frame.mdbcw_page);
422bc174764SAziz IDOMAR
423bc174764SAziz IDOMAR /*
424bc174764SAziz IDOMAR * Disable this doorbell channel from contributing to the MBX
425bc174764SAziz IDOMAR * combined interrupt.
426bc174764SAziz IDOMAR */
427bc174764SAziz IDOMAR mdbcw_reg[channel].mdbcw_ctrl &=
428bc174764SAziz IDOMAR ~(MHU_V3_X_MDBCW_CTRL_MBX_COMB_EN);
429bc174764SAziz IDOMAR } else {
430bc174764SAziz IDOMAR /* Only PBX and MBX frames are supported. */
431bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
432bc174764SAziz IDOMAR }
433bc174764SAziz IDOMAR
434bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
435bc174764SAziz IDOMAR }
436bc174764SAziz IDOMAR
mhu_v3_x_channel_interrupt_clear(const struct mhu_v3_x_dev_t * dev,const uint32_t channel,enum mhu_v3_x_channel_type_t ch_type)437bc174764SAziz IDOMAR enum mhu_v3_x_error_t mhu_v3_x_channel_interrupt_clear(
438bc174764SAziz IDOMAR const struct mhu_v3_x_dev_t *dev, const uint32_t channel,
439bc174764SAziz IDOMAR enum mhu_v3_x_channel_type_t ch_type)
440bc174764SAziz IDOMAR {
441bc174764SAziz IDOMAR enum mhu_v3_x_error_t status;
442bc174764SAziz IDOMAR union _mhu_v3_x_frame_t *p_mhu;
443bc174764SAziz IDOMAR struct _mhu_v3_x_pdbcw_reg_t *pdbcw_reg;
444bc174764SAziz IDOMAR
445bc174764SAziz IDOMAR /* Get dev->base if it is valid or return an error if dev is not */
446bc174764SAziz IDOMAR status = get_dev_base(dev, &p_mhu);
447bc174764SAziz IDOMAR if (status != MHU_V_3_X_ERR_NONE) {
448bc174764SAziz IDOMAR return status;
449bc174764SAziz IDOMAR }
450bc174764SAziz IDOMAR
451bc174764SAziz IDOMAR /* Only doorbell channel is supported */
452bc174764SAziz IDOMAR if (ch_type != MHU_V3_X_CHANNEL_TYPE_DBCH) {
453bc174764SAziz IDOMAR return MHU_V_3_X_ERR_UNSUPPORTED;
454bc174764SAziz IDOMAR }
455bc174764SAziz IDOMAR
456bc174764SAziz IDOMAR /*
457bc174764SAziz IDOMAR * Only postbox doorbell channel transfer acknowledge interrupt can be
458bc174764SAziz IDOMAR * cleared manually.
459bc174764SAziz IDOMAR *
460bc174764SAziz IDOMAR * To clear MBX interrupt the unmasked status must be cleared using
461bc174764SAziz IDOMAR * mhu_v3_x_doorbell_clear.
462bc174764SAziz IDOMAR */
463bc174764SAziz IDOMAR if (dev->frame != MHU_V3_X_PBX_FRAME) {
464bc174764SAziz IDOMAR return MHU_V_3_X_ERR_INVALID_PARAM;
465bc174764SAziz IDOMAR }
466bc174764SAziz IDOMAR
467bc174764SAziz IDOMAR p_mhu = (union _mhu_v3_x_frame_t *)dev->base;
468bc174764SAziz IDOMAR pdbcw_reg = (struct _mhu_v3_x_pdbcw_reg_t *)&(
469bc174764SAziz IDOMAR p_mhu->pbx_frame.pdbcw_page);
470bc174764SAziz IDOMAR
471bc174764SAziz IDOMAR /* Clear channel transfer acknowledge event interrupt */
472bc174764SAziz IDOMAR pdbcw_reg[channel].pdbcw_int_clr |= 0x1;
473bc174764SAziz IDOMAR
474bc174764SAziz IDOMAR return MHU_V_3_X_ERR_NONE;
475bc174764SAziz IDOMAR }
476