5 #include <kernel/timer.h>
7 static void mailbox_write_timeout(timer_list_t
*timer __UNUSED
, timer_ticks_t now __UNUSED
,
10 // arg is data | channel.
15 static void mailbox_read_timeout(timer_list_t
*timer __UNUSED
, timer_ticks_t now __UNUSED
,
23 void mailbox_write(uint32_t data
, uint8_t channel
)
25 // Only accesses of different peripherals can get out of order,
26 // so we'll do a DMB at the start of each peripheral access.
28 // Interrupts that access peripherals would do a DMB at, both,
29 // the beginning and the end.
30 data_memory_barrier();
33 timer_setup(&timer
, MAILBOX_TIMEOUT
, 0, mailbox_write_timeout
, 0);
35 while (mmio_reg_read(MAILBOX_BASE
+ MAILBOX_STATUS
) & (1 << 31));
38 mmio_reg_write(MAILBOX_BASE
+ MAILBOX_WRITE
, data
| channel
);
41 uint32_t mailbox_read(uint8_t channel
)
43 data_memory_barrier();
47 timer_setup(&timer
, MAILBOX_TIMEOUT
, 0, mailbox_read_timeout
, 0);
49 while (mmio_reg_read(MAILBOX_BASE
+ MAILBOX_STATUS
) & (1 << 30));
52 } while (((data
= mmio_reg_read(MAILBOX_BASE
)) & 0xF) != channel
);