xref: /arm-trusted-firmware/drivers/arm/mhu/mhu_v2_x.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <stdbool.h>
9*91f16700Schasinglulu #include <stdint.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include "mhu_v2_x.h"
12*91f16700Schasinglulu 
13*91f16700Schasinglulu #define MHU_V2_X_MAX_CHANNELS		124
14*91f16700Schasinglulu #define MHU_V2_1_MAX_CHCOMB_INT		4
15*91f16700Schasinglulu #define ENABLE				0x1
16*91f16700Schasinglulu #define DISABLE				0x0
17*91f16700Schasinglulu #define CLEAR_INTR			0x1
18*91f16700Schasinglulu #define CH_PER_CH_COMB			0x20
19*91f16700Schasinglulu #define SEND_FRAME(p_mhu)		((struct mhu_v2_x_send_frame_t *)p_mhu)
20*91f16700Schasinglulu #define RECV_FRAME(p_mhu)		((struct mhu_v2_x_recv_frame_t *)p_mhu)
21*91f16700Schasinglulu 
22*91f16700Schasinglulu #define MHU_MAJOR_REV_V2		0x1u
23*91f16700Schasinglulu #define MHU_MINOR_REV_2_0		0x0u
24*91f16700Schasinglulu #define MHU_MINOR_REV_2_1		0x1u
25*91f16700Schasinglulu 
26*91f16700Schasinglulu struct mhu_v2_x_send_ch_window_t {
27*91f16700Schasinglulu 	/* Offset: 0x00 (R/ ) Channel Status */
28*91f16700Schasinglulu 	volatile uint32_t ch_st;
29*91f16700Schasinglulu 	/* Offset: 0x04 (R/ ) Reserved */
30*91f16700Schasinglulu 	volatile uint32_t reserved_0;
31*91f16700Schasinglulu 	/* Offset: 0x08 (R/ ) Reserved */
32*91f16700Schasinglulu 	volatile uint32_t reserved_1;
33*91f16700Schasinglulu 	/* Offset: 0x0C ( /W) Channel Set */
34*91f16700Schasinglulu 	volatile uint32_t ch_set;
35*91f16700Schasinglulu 	/* Offset: 0x10 (R/ ) Channel Interrupt Status (Reserved in 2.0) */
36*91f16700Schasinglulu 	volatile uint32_t ch_int_st;
37*91f16700Schasinglulu 	/* Offset: 0x14 ( /W) Channel Interrupt Clear  (Reserved in 2.0) */
38*91f16700Schasinglulu 	volatile uint32_t ch_int_clr;
39*91f16700Schasinglulu 	/* Offset: 0x18 (R/W) Channel Interrupt Enable (Reserved in 2.0) */
40*91f16700Schasinglulu 	volatile uint32_t ch_int_en;
41*91f16700Schasinglulu 	/* Offset: 0x1C (R/ ) Reserved */
42*91f16700Schasinglulu 	volatile uint32_t reserved_2;
43*91f16700Schasinglulu };
44*91f16700Schasinglulu 
45*91f16700Schasinglulu struct mhu_v2_x_send_frame_t {
46*91f16700Schasinglulu 	/* Offset: 0x000 ( / ) Sender Channel Window 0 -123 */
47*91f16700Schasinglulu 	struct mhu_v2_x_send_ch_window_t send_ch_window[MHU_V2_X_MAX_CHANNELS];
48*91f16700Schasinglulu 	/* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */
49*91f16700Schasinglulu 	volatile uint32_t mhu_cfg;
50*91f16700Schasinglulu 	/* Offset: 0xF84 (R/W) Response Configuration */
51*91f16700Schasinglulu 	volatile uint32_t resp_cfg;
52*91f16700Schasinglulu 	/* Offset: 0xF88 (R/W) Access Request */
53*91f16700Schasinglulu 	volatile uint32_t access_request;
54*91f16700Schasinglulu 	/* Offset: 0xF8C (R/ ) Access Ready */
55*91f16700Schasinglulu 	volatile uint32_t access_ready;
56*91f16700Schasinglulu 	/* Offset: 0xF90 (R/ ) Interrupt Status */
57*91f16700Schasinglulu 	volatile uint32_t int_st;
58*91f16700Schasinglulu 	/* Offset: 0xF94 ( /W) Interrupt Clear */
59*91f16700Schasinglulu 	volatile uint32_t int_clr;
60*91f16700Schasinglulu 	/* Offset: 0xF98 (R/W) Interrupt Enable */
61*91f16700Schasinglulu 	volatile uint32_t int_en;
62*91f16700Schasinglulu 	/* Offset: 0xF9C (R/ ) Reserved */
63*91f16700Schasinglulu 	volatile uint32_t reserved_0;
64*91f16700Schasinglulu 	/* Offset: 0xFA0 (R/W) Channel Combined IRQ Stat (Reserved in 2.0) */
65*91f16700Schasinglulu 	volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT];
66*91f16700Schasinglulu 	/* Offset: 0xFC4 (R/ ) Reserved */
67*91f16700Schasinglulu 	volatile uint32_t reserved_1[6];
68*91f16700Schasinglulu 	/* Offset: 0xFC8 (R/ ) Implementer Identification Register */
69*91f16700Schasinglulu 	volatile uint32_t iidr;
70*91f16700Schasinglulu 	/* Offset: 0xFCC (R/ ) Architecture Identification Register */
71*91f16700Schasinglulu 	volatile uint32_t aidr;
72*91f16700Schasinglulu 	/* Offset: 0xFD0 (R/ )  */
73*91f16700Schasinglulu 	volatile uint32_t pid_1[4];
74*91f16700Schasinglulu 	/* Offset: 0xFE0 (R/ )  */
75*91f16700Schasinglulu 	volatile uint32_t pid_0[4];
76*91f16700Schasinglulu 	/* Offset: 0xFF0 (R/ )  */
77*91f16700Schasinglulu 	volatile uint32_t cid[4];
78*91f16700Schasinglulu };
79*91f16700Schasinglulu 
80*91f16700Schasinglulu struct mhu_v2_x_rec_ch_window_t {
81*91f16700Schasinglulu 	/* Offset: 0x00 (R/ ) Channel Status */
82*91f16700Schasinglulu 	volatile uint32_t ch_st;
83*91f16700Schasinglulu 	/* Offset: 0x04 (R/ ) Channel Status Masked */
84*91f16700Schasinglulu 	volatile uint32_t ch_st_msk;
85*91f16700Schasinglulu 	/* Offset: 0x08 ( /W) Channel Clear */
86*91f16700Schasinglulu 	volatile uint32_t ch_clr;
87*91f16700Schasinglulu 	/* Offset: 0x0C (R/ ) Reserved */
88*91f16700Schasinglulu 	volatile uint32_t reserved_0;
89*91f16700Schasinglulu 	/* Offset: 0x10 (R/ ) Channel Mask Status */
90*91f16700Schasinglulu 	volatile uint32_t ch_msk_st;
91*91f16700Schasinglulu 	/* Offset: 0x14 ( /W) Channel Mask Set */
92*91f16700Schasinglulu 	volatile uint32_t ch_msk_set;
93*91f16700Schasinglulu 	/* Offset: 0x18 ( /W) Channel Mask Clear */
94*91f16700Schasinglulu 	volatile uint32_t ch_msk_clr;
95*91f16700Schasinglulu 	/* Offset: 0x1C (R/ ) Reserved */
96*91f16700Schasinglulu 	volatile uint32_t reserved_1;
97*91f16700Schasinglulu };
98*91f16700Schasinglulu 
99*91f16700Schasinglulu struct mhu_v2_x_recv_frame_t {
100*91f16700Schasinglulu 	/* Offset: 0x000 ( / ) Receiver Channel Window 0 -123 */
101*91f16700Schasinglulu 	struct mhu_v2_x_rec_ch_window_t rec_ch_window[MHU_V2_X_MAX_CHANNELS];
102*91f16700Schasinglulu 	/* Offset: 0xF80 (R/ ) Message Handling Unit Configuration */
103*91f16700Schasinglulu 	volatile uint32_t mhu_cfg;
104*91f16700Schasinglulu 	/* Offset: 0xF84 (R/ ) Reserved */
105*91f16700Schasinglulu 	volatile uint32_t reserved_0[3];
106*91f16700Schasinglulu 	/* Offset: 0xF90 (R/ ) Interrupt Status (Reserved in 2.0) */
107*91f16700Schasinglulu 	volatile uint32_t int_st;
108*91f16700Schasinglulu 	/* Offset: 0xF94 (R/ ) Interrupt Clear  (Reserved in 2.0) */
109*91f16700Schasinglulu 	volatile uint32_t int_clr;
110*91f16700Schasinglulu 	/* Offset: 0xF98 (R/W) Interrupt Enable (Reserved in 2.0) */
111*91f16700Schasinglulu 	volatile uint32_t int_en;
112*91f16700Schasinglulu 	/* Offset: 0xF9C (R/ ) Reserved  */
113*91f16700Schasinglulu 	volatile uint32_t reserved_1;
114*91f16700Schasinglulu 	/* Offset: 0xFA0 (R/ ) Channel Combined IRQ Stat (Reserved in 2.0) */
115*91f16700Schasinglulu 	volatile uint32_t ch_comb_int_st[MHU_V2_1_MAX_CHCOMB_INT];
116*91f16700Schasinglulu 	/* Offset: 0xFB0 (R/ ) Reserved */
117*91f16700Schasinglulu 	volatile uint32_t reserved_2[6];
118*91f16700Schasinglulu 	/* Offset: 0xFC8 (R/ ) Implementer Identification Register */
119*91f16700Schasinglulu 	volatile uint32_t iidr;
120*91f16700Schasinglulu 	/* Offset: 0xFCC (R/ ) Architecture Identification Register */
121*91f16700Schasinglulu 	volatile uint32_t aidr;
122*91f16700Schasinglulu 	/* Offset: 0xFD0 (R/ )  */
123*91f16700Schasinglulu 	volatile uint32_t pid_1[4];
124*91f16700Schasinglulu 	/* Offset: 0xFE0 (R/ )  */
125*91f16700Schasinglulu 	volatile uint32_t pid_0[4];
126*91f16700Schasinglulu 	/* Offset: 0xFF0 (R/ )  */
127*91f16700Schasinglulu 	volatile uint32_t cid[4];
128*91f16700Schasinglulu };
129*91f16700Schasinglulu 
130*91f16700Schasinglulu union mhu_v2_x_frame {
131*91f16700Schasinglulu 	struct mhu_v2_x_send_frame_t send_frame;
132*91f16700Schasinglulu 	struct mhu_v2_x_recv_frame_t recv_frame;
133*91f16700Schasinglulu };
134*91f16700Schasinglulu 
135*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_driver_init(struct mhu_v2_x_dev_t *dev,
136*91f16700Schasinglulu 	 enum mhu_v2_x_supported_revisions rev)
137*91f16700Schasinglulu {
138*91f16700Schasinglulu 	uint32_t AIDR = 0;
139*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
140*91f16700Schasinglulu 
141*91f16700Schasinglulu 	assert(dev != NULL);
142*91f16700Schasinglulu 
143*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
144*91f16700Schasinglulu 
145*91f16700Schasinglulu 	if (dev->is_initialized) {
146*91f16700Schasinglulu 		return MHU_V_2_X_ERR_ALREADY_INIT;
147*91f16700Schasinglulu 	}
148*91f16700Schasinglulu 
149*91f16700Schasinglulu 	if (rev == MHU_REV_READ_FROM_HW) {
150*91f16700Schasinglulu 		/* Read revision from HW */
151*91f16700Schasinglulu 		if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
152*91f16700Schasinglulu 			AIDR = p_mhu->recv_frame.aidr;
153*91f16700Schasinglulu 		} else {
154*91f16700Schasinglulu 			AIDR = p_mhu->send_frame.aidr;
155*91f16700Schasinglulu 		}
156*91f16700Schasinglulu 
157*91f16700Schasinglulu 		/* Get bits 7:4 to read major revision */
158*91f16700Schasinglulu 		if (((AIDR >> 4) & 0b1111) != MHU_MAJOR_REV_V2) {
159*91f16700Schasinglulu 			/* Unsupported MHU version */
160*91f16700Schasinglulu 			return MHU_V_2_X_ERR_UNSUPPORTED_VERSION;
161*91f16700Schasinglulu 		} /* No need to save major version, driver only supports MHUv2 */
162*91f16700Schasinglulu 
163*91f16700Schasinglulu 		/* Get bits 3:0 to read minor revision */
164*91f16700Schasinglulu 		dev->subversion = AIDR & 0b1111;
165*91f16700Schasinglulu 
166*91f16700Schasinglulu 		if (dev->subversion != MHU_MINOR_REV_2_0 &&
167*91f16700Schasinglulu 			dev->subversion != MHU_MINOR_REV_2_1) {
168*91f16700Schasinglulu 			/* Unsupported subversion */
169*91f16700Schasinglulu 			return MHU_V_2_X_ERR_UNSUPPORTED_VERSION;
170*91f16700Schasinglulu 		}
171*91f16700Schasinglulu 	} else {
172*91f16700Schasinglulu 		/* Revisions were provided by caller */
173*91f16700Schasinglulu 		if (rev == MHU_REV_2_0) {
174*91f16700Schasinglulu 			dev->subversion = MHU_MINOR_REV_2_0;
175*91f16700Schasinglulu 		} else if (rev == MHU_REV_2_1) {
176*91f16700Schasinglulu 			dev->subversion = MHU_MINOR_REV_2_1;
177*91f16700Schasinglulu 		} else {
178*91f16700Schasinglulu 			/* Unsupported subversion */
179*91f16700Schasinglulu 			return MHU_V_2_X_ERR_UNSUPPORTED_VERSION;
180*91f16700Schasinglulu 		} /* No need to save major version, driver only supports MHUv2 */
181*91f16700Schasinglulu 	}
182*91f16700Schasinglulu 
183*91f16700Schasinglulu 	dev->is_initialized = true;
184*91f16700Schasinglulu 
185*91f16700Schasinglulu 	return MHU_V_2_X_ERR_NONE;
186*91f16700Schasinglulu }
187*91f16700Schasinglulu 
188*91f16700Schasinglulu uint32_t mhu_v2_x_get_num_channel_implemented(const struct mhu_v2_x_dev_t *dev)
189*91f16700Schasinglulu {
190*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
191*91f16700Schasinglulu 
192*91f16700Schasinglulu 	assert(dev != NULL);
193*91f16700Schasinglulu 
194*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
195*91f16700Schasinglulu 
196*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
197*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
198*91f16700Schasinglulu 	}
199*91f16700Schasinglulu 
200*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_SENDER_FRAME) {
201*91f16700Schasinglulu 		return (SEND_FRAME(p_mhu))->mhu_cfg;
202*91f16700Schasinglulu 	} else {
203*91f16700Schasinglulu 		assert(dev->frame == MHU_V2_X_RECEIVER_FRAME);
204*91f16700Schasinglulu 		return (RECV_FRAME(p_mhu))->mhu_cfg;
205*91f16700Schasinglulu 	}
206*91f16700Schasinglulu }
207*91f16700Schasinglulu 
208*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_channel_send(const struct mhu_v2_x_dev_t *dev,
209*91f16700Schasinglulu 	 uint32_t channel, uint32_t val)
210*91f16700Schasinglulu {
211*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
212*91f16700Schasinglulu 
213*91f16700Schasinglulu 	assert(dev != NULL);
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
216*91f16700Schasinglulu 
217*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
218*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
219*91f16700Schasinglulu 	}
220*91f16700Schasinglulu 
221*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_SENDER_FRAME) {
222*91f16700Schasinglulu 		(SEND_FRAME(p_mhu))->send_ch_window[channel].ch_set = val;
223*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NONE;
224*91f16700Schasinglulu 	} else {
225*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
226*91f16700Schasinglulu 	}
227*91f16700Schasinglulu }
228*91f16700Schasinglulu 
229*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_channel_poll(const struct mhu_v2_x_dev_t *dev,
230*91f16700Schasinglulu 	 uint32_t channel, uint32_t *value)
231*91f16700Schasinglulu {
232*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
233*91f16700Schasinglulu 
234*91f16700Schasinglulu 	assert(dev != NULL);
235*91f16700Schasinglulu 
236*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
237*91f16700Schasinglulu 
238*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
239*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
240*91f16700Schasinglulu 	}
241*91f16700Schasinglulu 
242*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_SENDER_FRAME) {
243*91f16700Schasinglulu 		*value = (SEND_FRAME(p_mhu))->send_ch_window[channel].ch_st;
244*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NONE;
245*91f16700Schasinglulu 	} else {
246*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
247*91f16700Schasinglulu 	}
248*91f16700Schasinglulu }
249*91f16700Schasinglulu 
250*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_channel_clear(const struct mhu_v2_x_dev_t *dev,
251*91f16700Schasinglulu 	 uint32_t channel)
252*91f16700Schasinglulu {
253*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
254*91f16700Schasinglulu 
255*91f16700Schasinglulu 	assert(dev != NULL);
256*91f16700Schasinglulu 
257*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
258*91f16700Schasinglulu 
259*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
260*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
261*91f16700Schasinglulu 	}
262*91f16700Schasinglulu 
263*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
264*91f16700Schasinglulu 		(RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_clr = UINT32_MAX;
265*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NONE;
266*91f16700Schasinglulu 	} else {
267*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
268*91f16700Schasinglulu 	}
269*91f16700Schasinglulu }
270*91f16700Schasinglulu 
271*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_channel_receive(
272*91f16700Schasinglulu 	 const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t *value)
273*91f16700Schasinglulu {
274*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
275*91f16700Schasinglulu 
276*91f16700Schasinglulu 	assert(dev != NULL);
277*91f16700Schasinglulu 
278*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
279*91f16700Schasinglulu 
280*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
281*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
282*91f16700Schasinglulu 	}
283*91f16700Schasinglulu 
284*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
285*91f16700Schasinglulu 		*value = (RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_st;
286*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NONE;
287*91f16700Schasinglulu 	} else {
288*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
289*91f16700Schasinglulu 	}
290*91f16700Schasinglulu }
291*91f16700Schasinglulu 
292*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_channel_mask_set(
293*91f16700Schasinglulu 	 const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask)
294*91f16700Schasinglulu {
295*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
296*91f16700Schasinglulu 
297*91f16700Schasinglulu 	assert(dev != NULL);
298*91f16700Schasinglulu 
299*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
300*91f16700Schasinglulu 
301*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
302*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
303*91f16700Schasinglulu 	}
304*91f16700Schasinglulu 
305*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
306*91f16700Schasinglulu 		(RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_set = mask;
307*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NONE;
308*91f16700Schasinglulu 	} else {
309*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
310*91f16700Schasinglulu 	}
311*91f16700Schasinglulu }
312*91f16700Schasinglulu 
313*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_channel_mask_clear(
314*91f16700Schasinglulu 	 const struct mhu_v2_x_dev_t *dev, uint32_t channel, uint32_t mask)
315*91f16700Schasinglulu {
316*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
317*91f16700Schasinglulu 
318*91f16700Schasinglulu 	assert(dev != NULL);
319*91f16700Schasinglulu 
320*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
321*91f16700Schasinglulu 
322*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
323*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
324*91f16700Schasinglulu 	}
325*91f16700Schasinglulu 
326*91f16700Schasinglulu 	if (dev->frame == MHU_V2_X_RECEIVER_FRAME) {
327*91f16700Schasinglulu 		(RECV_FRAME(p_mhu))->rec_ch_window[channel].ch_msk_clr = mask;
328*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NONE;
329*91f16700Schasinglulu 	} else {
330*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
331*91f16700Schasinglulu 	}
332*91f16700Schasinglulu }
333*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_initiate_transfer(
334*91f16700Schasinglulu 	 const struct mhu_v2_x_dev_t *dev)
335*91f16700Schasinglulu {
336*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
337*91f16700Schasinglulu 
338*91f16700Schasinglulu 	assert(dev != NULL);
339*91f16700Schasinglulu 
340*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
341*91f16700Schasinglulu 
342*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
343*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
344*91f16700Schasinglulu 	}
345*91f16700Schasinglulu 
346*91f16700Schasinglulu 	if (dev->frame != MHU_V2_X_SENDER_FRAME) {
347*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
348*91f16700Schasinglulu 	}
349*91f16700Schasinglulu 
350*91f16700Schasinglulu 	(SEND_FRAME(p_mhu))->access_request = ENABLE;
351*91f16700Schasinglulu 
352*91f16700Schasinglulu 	while (!((SEND_FRAME(p_mhu))->access_ready)) {
353*91f16700Schasinglulu 		/* Wait in a loop for access ready signal to be high */
354*91f16700Schasinglulu 		;
355*91f16700Schasinglulu 	}
356*91f16700Schasinglulu 
357*91f16700Schasinglulu 	return MHU_V_2_X_ERR_NONE;
358*91f16700Schasinglulu }
359*91f16700Schasinglulu 
360*91f16700Schasinglulu enum mhu_v2_x_error_t mhu_v2_x_close_transfer(const struct mhu_v2_x_dev_t *dev)
361*91f16700Schasinglulu {
362*91f16700Schasinglulu 	union mhu_v2_x_frame *p_mhu;
363*91f16700Schasinglulu 
364*91f16700Schasinglulu 	assert(dev != NULL);
365*91f16700Schasinglulu 
366*91f16700Schasinglulu 	p_mhu = (union mhu_v2_x_frame *)dev->base;
367*91f16700Schasinglulu 
368*91f16700Schasinglulu 	if (!(dev->is_initialized)) {
369*91f16700Schasinglulu 		return MHU_V_2_X_ERR_NOT_INIT;
370*91f16700Schasinglulu 	}
371*91f16700Schasinglulu 
372*91f16700Schasinglulu 	if (dev->frame != MHU_V2_X_SENDER_FRAME) {
373*91f16700Schasinglulu 		return MHU_V_2_X_ERR_INVALID_ARG;
374*91f16700Schasinglulu 	}
375*91f16700Schasinglulu 
376*91f16700Schasinglulu 	(SEND_FRAME(p_mhu))->access_request = DISABLE;
377*91f16700Schasinglulu 
378*91f16700Schasinglulu 	return MHU_V_2_X_ERR_NONE;
379*91f16700Schasinglulu }
380