mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-13 22:00:40 +00:00
98 lines
2.6 KiB
C
98 lines
2.6 KiB
C
#include "../include/io.h"
|
|
#include "../include/mb.h"
|
|
|
|
// The buffer must be 16-byte aligned as only the upper 28 bits of the address can be passed via the mailbox
|
|
volatile unsigned int __attribute__((aligned(16))) mbox[36];
|
|
|
|
enum {
|
|
VIDEOCORE_MBOX = (PERIPHERAL_BASE + 0x0000B880),
|
|
MBOX_READ = (VIDEOCORE_MBOX + 0x0),
|
|
MBOX_POLL = (VIDEOCORE_MBOX + 0x10),
|
|
MBOX_SENDER = (VIDEOCORE_MBOX + 0x14),
|
|
MBOX_STATUS = (VIDEOCORE_MBOX + 0x18),
|
|
MBOX_CONFIG = (VIDEOCORE_MBOX + 0x1C),
|
|
MBOX_WRITE = (VIDEOCORE_MBOX + 0x20),
|
|
MBOX_RESPONSE = 0x80000000,
|
|
MBOX_FULL = 0x80000000,
|
|
MBOX_EMPTY = 0x40000000
|
|
};
|
|
|
|
unsigned int mbox_call(unsigned char ch)
|
|
{
|
|
// 28-bit address (MSB) and 4-bit value (LSB)
|
|
unsigned int r = ((unsigned int)((long) &mbox) &~ 0xF) | (ch & 0xF);
|
|
|
|
// Wait until we can write
|
|
while (mmio_read(MBOX_STATUS) & MBOX_FULL);
|
|
|
|
// Write the address of our buffer to the mailbox with the channel appended
|
|
mmio_write(MBOX_WRITE, r);
|
|
|
|
while (1) {
|
|
// Is there a reply?
|
|
while (mmio_read(MBOX_STATUS) & MBOX_EMPTY);
|
|
|
|
// Is it a reply to our message?
|
|
if (r == mmio_read(MBOX_READ)) return mbox[1]==MBOX_RESPONSE; // Is it successful?
|
|
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int get_max_clock()
|
|
{
|
|
mbox[0] = 8*4; // Length of message in bytes
|
|
mbox[1] = MBOX_REQUEST;
|
|
mbox[2] = MBOX_TAG_GETCLKMAXM; // Tag identifier
|
|
mbox[3] = 8; // Value size in bytes
|
|
mbox[4] = 0; // Value size in bytes
|
|
mbox[5] = 0x3; // Value
|
|
mbox[6] = 0; // Rate
|
|
mbox[7] = MBOX_TAG_LAST;
|
|
|
|
if (mbox_call(MBOX_CH_PROP)) {
|
|
if (mbox[5] == 0x3) {
|
|
return mbox[6];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int get_clock_rate()
|
|
{
|
|
mbox[0] = 8*4; // Length of message in bytes
|
|
mbox[1] = MBOX_REQUEST;
|
|
mbox[2] = MBOX_TAG_GETCLKRATE; // Tag identifier
|
|
mbox[3] = 8; // Value size in bytes
|
|
mbox[4] = 0; // Value size in bytes
|
|
mbox[5] = 0x3; // Value
|
|
mbox[6] = 0; // Rate
|
|
mbox[7] = MBOX_TAG_LAST;
|
|
|
|
if (mbox_call(MBOX_CH_PROP)) {
|
|
if (mbox[5] == 0x3) {
|
|
return mbox[6];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int set_clock_rate(unsigned int rate)
|
|
{
|
|
mbox[0] = 9*4; // Length of message in bytes
|
|
mbox[1] = MBOX_REQUEST;
|
|
mbox[2] = MBOX_TAG_SETCLKRATE; // Tag identifier
|
|
mbox[3] = 12; // Value size in bytes
|
|
mbox[4] = 0; // Value size in bytes
|
|
mbox[5] = 0x3; // Value
|
|
mbox[6] = rate; // Rate
|
|
mbox[7] = 0; // Rate
|
|
mbox[8] = MBOX_TAG_LAST;
|
|
|
|
if (mbox_call(MBOX_CH_PROP)) {
|
|
if (mbox[5] == 0x3 && mbox[6] == rate) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|