Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use mailbox to get hwrev #495

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,26 @@ static int mbox_property(int file_desc, void *buf) {
return ret_val;
}

uint32_t get_hwver(int file_desc) {
int i=0;
uint32_t p[32];

p[i++] = 0; // size
p[i++] = 0x00000000; // process request

p[i++] = 0x10002; // (the tag id)
p[i++] = 4; // (size of the buffer)
p[i++] = 0; // (size of the data)
p[i++] = 0; // (buffer)

p[i++] = 0x00000000; // end tag
p[0] = i*sizeof *p; // actual size

mbox_property(file_desc, p);

return p[5];
}

uint32_t mem_alloc(int file_desc, uint32_t size, uint32_t align, uint32_t flags) {
int i=0;
uint32_t p[32];
Expand Down
1 change: 1 addition & 0 deletions mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ int mbox_open(void);
void mbox_close(int file_desc);

unsigned get_version(int file_desc);
uint32_t get_hwver(int file_desc);
unsigned mem_alloc(int file_desc, unsigned size, unsigned align, unsigned flags);
unsigned mem_free(int file_desc, unsigned handle);
unsigned mem_lock(int file_desc, unsigned handle);
Expand Down
79 changes: 12 additions & 67 deletions rpihw.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <byteswap.h>

#include "mailbox.h"
#include "rpihw.h"


Expand Down Expand Up @@ -503,86 +503,31 @@ static const rpi_hw_t rpi_hw_info[] = {
};


const rpi_hw_t *rpi_hw_detect(void)
const rpi_hw_t *rpi_hw_detect(int file_desc)
{
const rpi_hw_t *result = NULL;
uint32_t rev;
unsigned i;

#ifdef __aarch64__
// On ARM64, read revision from /proc/device-tree as it is not shown in
// /proc/cpuinfo
FILE *f = fopen("/proc/device-tree/system/linux,revision", "r");
if (!f)
{
return NULL;
}
size_t read = fread(&rev, 1, sizeof(uint32_t), f);
if (read != sizeof(uint32_t))
goto done;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
rev = bswap_32(rev); // linux,revision appears to be in big endian
#endif
rev = get_hwver(file_desc);

// Take out warranty and manufacturer bits
rev &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);

for (i = 0; i < (sizeof(rpi_hw_info) / sizeof(rpi_hw_info[0])); i++)
{
uint32_t hwver = rpi_hw_info[i].hwver;
if (rev == hwver)
{
result = &rpi_hw_info[i];

goto done;
}
}
#else
FILE *f = fopen("/proc/cpuinfo", "r");
char line[LINE_WIDTH_MAX];

if (!f)
{
return NULL;
}
// Take out warranty and manufacturer bits
hwver &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);

while (fgets(line, LINE_WIDTH_MAX - 1, f))
{
if (strstr(line, HW_VER_STRING))
if (rev == hwver)
{
char *substr;

substr = strstr(line, ": ");
if (!substr)
{
continue;
}

errno = 0;
rev = strtoul(&substr[1], NULL, 16); // Base 16
if (errno)
{
continue;
}

for (i = 0; i < (sizeof(rpi_hw_info) / sizeof(rpi_hw_info[0])); i++)
{
uint32_t hwver = rpi_hw_info[i].hwver;

// Take out warranty and manufacturer bits
hwver &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);
rev &= ~(RPI_WARRANTY_MASK | RPI_MANUFACTURER_MASK);

if (rev == hwver)
{
result = &rpi_hw_info[i];

goto done;
}
}
result = &rpi_hw_info[i];
printf("%08x: %s\n", rpi_hw_info[i].hwver, rpi_hw_info[i].desc);
break;
}
}
#endif
done:
fclose(f);

return result;
}

2 changes: 1 addition & 1 deletion rpihw.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ typedef struct {
} rpi_hw_t;


const rpi_hw_t *rpi_hw_detect(void);
const rpi_hw_t *rpi_hw_detect(int file_desc);


#endif /* __RPIHW_H__ */
26 changes: 13 additions & 13 deletions ws2811.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,13 +897,6 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811)
const rpi_hw_t *rpi_hw;
int chan;

ws2811->rpi_hw = rpi_hw_detect();
if (!ws2811->rpi_hw)
{
return WS2811_ERROR_HW_NOT_SUPPORTED;
}
rpi_hw = ws2811->rpi_hw;

ws2811->device = malloc(sizeof(*ws2811->device));
if (!ws2811->device)
{
Expand All @@ -912,6 +905,19 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811)
memset(ws2811->device, 0, sizeof(*ws2811->device));
device = ws2811->device;

device->mbox.handle = mbox_open();
if (device->mbox.handle == -1)
{
return WS2811_ERROR_MAILBOX_DEVICE;
}

ws2811->rpi_hw = rpi_hw_detect(device->mbox.handle);
if (!ws2811->rpi_hw)
{
return WS2811_ERROR_HW_NOT_SUPPORTED;
}
rpi_hw = ws2811->rpi_hw;

if (check_hwver_and_gpionum(ws2811) < 0)
{
return WS2811_ERROR_ILLEGAL_GPIO;
Expand All @@ -938,12 +944,6 @@ ws2811_return_t ws2811_init(ws2811_t *ws2811)
// Round up to page size multiple
device->mbox.size = (device->mbox.size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);

device->mbox.handle = mbox_open();
if (device->mbox.handle == -1)
{
return WS2811_ERROR_MAILBOX_DEVICE;
}

device->mbox.mem_ref = mem_alloc(device->mbox.handle, device->mbox.size, PAGE_SIZE,
rpi_hw->videocore_base == 0x40000000 ? 0xC : 0x4);
if (device->mbox.mem_ref == 0)
Expand Down