aboutsummaryrefslogtreecommitdiffstats
path: root/boards/base/RaspberryPi/rpi_mailbox.c
blob: 798cbb1f07ac4b4eb51b3137ae2f3559553c2433 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
 * Access system mailboxes
 */
#include "rpi_mailbox.h"

/* Mailbox memory addresses */
static volatile unsigned int *MAILBOX0READ = (unsigned int *) (0x2000b880);
static volatile unsigned int *MAILBOX0STATUS = (unsigned int *) (0x2000b898);
static volatile unsigned int *MAILBOX0WRITE = (unsigned int *) (0x2000b8a0);

/* Bit 31 set in status register if the write mailbox is full */
#define MAILBOX_FULL 0x80000000

/* Bit 30 set in status register if the read mailbox is empty */
#define MAILBOX_EMPTY 0x40000000

unsigned int rpi_readmailbox(unsigned int channel)
{
	unsigned int val;

	if (channel > 15)
		return 0xFFFFFFFF;

	/* Wait for mailbox to be full */
	while (*MAILBOX0STATUS & MAILBOX_EMPTY);

	val = *MAILBOX0READ;

	if ((val & 15) == channel)
		return (val & 0xFFFFFFF0);
	else
		return 0xFFFFFFFF;
}

void rpi_writemailbox(unsigned int channel, unsigned int data)
{
	if (channel > 15)
		return;

	if (data & 0x000F)
		return;

	/* Wait for mailbox to be not full */
	while (*MAILBOX0STATUS & MAILBOX_FULL);

	*MAILBOX0WRITE = (data | channel);
}