Compare commits
1 commit
master
...
spi-layer-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3e35a54ee |
5 changed files with 80 additions and 21 deletions
1
eeprom.h
1
eeprom.h
|
|
@ -59,4 +59,5 @@ int eeprom_verify(llio_t *self, char *bitfile_name, u32 start_address);
|
|||
void eeprom_init(llio_t *self);
|
||||
void eeprom_cleanup(llio_t *self);
|
||||
|
||||
extern spi_eeprom_dev_t eeprom_access;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ extern spi_eeprom_dev_t eeprom_access;
|
|||
|
||||
// spi access via hm2 registers
|
||||
|
||||
static void wait_for_data_hm2(llio_t *self) {
|
||||
void wait_for_data_hm2(llio_t *self) {
|
||||
u32 i = 0;
|
||||
u32 data = 0;
|
||||
|
||||
|
|
@ -309,13 +309,13 @@ static u8 recv_byte_epp(llio_t *self) {
|
|||
|
||||
// pci flash
|
||||
|
||||
static void send_address(llio_t *self, u32 addr) {
|
||||
void send_address(llio_t *self, u32 addr) {
|
||||
eeprom_access.send_byte(self, (addr >> 16) & 0xFF);
|
||||
eeprom_access.send_byte(self, (addr >> 8) & 0xFF);
|
||||
eeprom_access.send_byte(self, addr & 0xFF);
|
||||
}
|
||||
|
||||
static void write_enable(llio_t *self) {
|
||||
void write_enable(llio_t *self) {
|
||||
eeprom_access.prefix(self);
|
||||
eeprom_access.send_byte(self, SPI_CMD_WRITE_ENABLE);
|
||||
eeprom_access.suffix(self);
|
||||
|
|
@ -342,7 +342,7 @@ u8 read_flash_id(llio_t *self) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void wait_for_write(llio_t *self) {
|
||||
void wait_for_write(llio_t *self) {
|
||||
u8 stat = read_status(self);
|
||||
|
||||
while ((stat & WRITE_IN_PROGRESS_MASK) != 0) {
|
||||
|
|
|
|||
62
spi_boards.c
62
spi_boards.c
|
|
@ -22,6 +22,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "eeprom_local.h"
|
||||
#include "eeprom.h"
|
||||
#include "spi_boards.h"
|
||||
#include "common.h"
|
||||
#include "spilbp.h"
|
||||
|
|
@ -29,6 +30,47 @@
|
|||
extern board_t boards[MAX_BOARDS];
|
||||
extern int boards_count;
|
||||
|
||||
#if (PAGE_SIZE * 16) > 4096
|
||||
#error This code does not work with EEPROM pages that big
|
||||
#endif
|
||||
|
||||
static void spi_read_page(llio_t *self, u32 addr, void *buff) {
|
||||
int i, j;
|
||||
u32 wide[4*PAGE_SIZE];
|
||||
|
||||
for(i=0, j=0; i<PAGE_SIZE; i++) {
|
||||
wide[j++] = spilbp_write_command(HM2_SPI_DATA_REG, 1, false);
|
||||
wide[j++] = 0;
|
||||
wide[j++] = spilbp_read_command(HM2_SPI_DATA_REG, 1, false);
|
||||
wide[j++] = 0;
|
||||
}
|
||||
eeprom_access.prefix(self);
|
||||
eeprom_access.send_byte(self, SPI_CMD_READ);
|
||||
send_address(self, addr);
|
||||
spilbp_transact(wide, sizeof(wide));
|
||||
eeprom_access.suffix(self);
|
||||
|
||||
for(i=0; i<PAGE_SIZE; i++) ((u8*)buff)[i] = wide[4*i+3];
|
||||
}
|
||||
|
||||
static void spi_write_page(llio_t *self, u32 addr, void *buff) {
|
||||
int i, j;
|
||||
u32 wide[2*PAGE_SIZE];
|
||||
|
||||
for(i=0, j=0; i<PAGE_SIZE; i++) {
|
||||
wide[j++] = spilbp_write_command(HM2_SPI_DATA_REG, 1, false);
|
||||
wide[j++] = ((u8*)buff)[i];
|
||||
}
|
||||
|
||||
write_enable(self);
|
||||
eeprom_access.prefix(self);
|
||||
eeprom_access.send_byte(self, SPI_CMD_PAGE_WRITE);
|
||||
send_address(self, addr);
|
||||
spilbp_transact(wide, sizeof(wide));
|
||||
eeprom_access.suffix(self);
|
||||
wait_for_write(self);
|
||||
}
|
||||
|
||||
static int spi_board_open(board_t *board) {
|
||||
eeprom_init(&(board->llio));
|
||||
board->flash_id = read_flash_id(&(board->llio));
|
||||
|
|
@ -38,6 +80,8 @@ static int spi_board_open(board_t *board) {
|
|||
} else {
|
||||
board->flash_start_address = 0;
|
||||
}
|
||||
eeprom_access.read_page = spi_read_page;
|
||||
eeprom_access.write_page = spi_write_page;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -54,27 +98,31 @@ void spi_boards_cleanup(board_access_t *access) {
|
|||
spilbp_release();
|
||||
}
|
||||
|
||||
void spi_read(llio_t *self, u32 off, void *buf, int sz) {
|
||||
return spilbp_read(off, buf, sz);
|
||||
static
|
||||
int spi_read(llio_t *self, u32 off, void *buf, int sz) {
|
||||
spilbp_read(off, buf, sz, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void spi_write(llio_t *self, u32 off, void *buf, int sz) {
|
||||
return spilbp_write(off, buf, sz);
|
||||
static
|
||||
int spi_write(llio_t *self, u32 off, void *buf, int sz) {
|
||||
spilbp_write(off, buf, sz, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void spi_boards_scan(board_access_t *access) {
|
||||
u32 buf[4];
|
||||
u32 cookie[] = {0x55aacafe, 0x54534f48, 0x32544f4d};
|
||||
if(spilbp_read(0x100, &buf, sizeof(buf)) < 0) return;
|
||||
if(spilbp_read(0x100, &buf, sizeof(buf), true) < 0) return;
|
||||
|
||||
if(memcmp(buf, cookie, sizeof(cookie))) {
|
||||
fprintf(stderr, "Unexpected cookie at 0000..000c:\n%08x %08x %08x\n",
|
||||
buf[0], buf[1], buf[2]);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
char ident[8];
|
||||
if(spilbp_read(buf[3] + 0xc, &ident, sizeof(ident)) < 0) return;
|
||||
if(spilbp_read(buf[3] + 0xc, &ident, sizeof(ident), true) < 0) return;
|
||||
|
||||
if(!memcmp(ident, "MESA7I90", 8)) {
|
||||
board_t *board = &boards[boards_count];
|
||||
|
|
|
|||
22
spilbp.c
22
spilbp.c
|
|
@ -33,21 +33,19 @@
|
|||
int sd = -1;
|
||||
struct spi_ioc_transfer settings;
|
||||
|
||||
static u32 read_command(u16 addr, unsigned nelem) {
|
||||
bool increment = true;
|
||||
u32 spilbp_read_command(u16 addr, unsigned nelem, bool increment) {
|
||||
return (addr << 16) | 0xA000 | (increment ? 0x800 : 0) | (nelem << 4);
|
||||
}
|
||||
|
||||
static u32 write_command(u16 addr, unsigned nelem) {
|
||||
bool increment = true;
|
||||
u32 spilbp_write_command(u16 addr, unsigned nelem, bool increment) {
|
||||
return (addr << 16) | 0xB000 | (increment ? 0x800 : 0) | (nelem << 4);
|
||||
}
|
||||
|
||||
|
||||
int spilbp_write(u16 addr, void *buffer, int size) {
|
||||
int spilbp_write(u16 addr, void *buffer, int size, bool increment) {
|
||||
if(size % 4 != 0) return -1;
|
||||
u32 txbuf[1+size/4];
|
||||
txbuf[0] = write_command(addr, size/4);
|
||||
txbuf[0] = spilbp_write_command(addr, size/4, increment);
|
||||
memcpy(txbuf + 1, buffer, size);
|
||||
|
||||
struct spi_ioc_transfer t;
|
||||
|
|
@ -60,10 +58,10 @@ int spilbp_write(u16 addr, void *buffer, int size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int spilbp_read(u16 addr, void *buffer, int size) {
|
||||
int spilbp_read(u16 addr, void *buffer, int size, bool increment) {
|
||||
if(size % 4 != 0) return -1;
|
||||
u32 trxbuf[1+size/4];
|
||||
trxbuf[0] = read_command(addr, size/4);
|
||||
trxbuf[0] = spilbp_read_command(addr, size/4, increment);
|
||||
memset(trxbuf+1, 0, size);
|
||||
|
||||
struct spi_ioc_transfer t;
|
||||
|
|
@ -78,6 +76,14 @@ int spilbp_read(u16 addr, void *buffer, int size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int spilbp_transact(void *buffer, size_t size) {
|
||||
struct spi_ioc_transfer t;
|
||||
t = settings;
|
||||
t.tx_buf = t.rx_buf = (uint64_t)(intptr_t)buffer;
|
||||
t.len = size;
|
||||
return ioctl(sd, SPI_IOC_MESSAGE(1), &t);
|
||||
}
|
||||
|
||||
void spilbp_print_info() {
|
||||
}
|
||||
|
||||
|
|
|
|||
8
spilbp.h
8
spilbp.h
|
|
@ -20,6 +20,7 @@
|
|||
#define __SPILBP_H
|
||||
|
||||
#include "types.h"
|
||||
#include <stdbool.h>
|
||||
#include "common.h"
|
||||
|
||||
#define SPILBP_SENDRECV_DEBUG 0
|
||||
|
|
@ -40,9 +41,12 @@ typedef struct {
|
|||
void spilbp_print_info();
|
||||
void spilbp_init(board_access_t *access);
|
||||
void spilbp_release();
|
||||
int spilbp_write(u32 addr, void *buffer, int size);
|
||||
int spilbp_read(u32 addr, void *buffer, int size);
|
||||
int spilbp_write(u32 addr, void *buffer, int size, bool increment);
|
||||
int spilbp_read(u32 addr, void *buffer, int size, bool increment);
|
||||
|
||||
u32 spilbp_read_command(u16 addr, unsigned nelem, bool increment);
|
||||
u32 spilbp_write_command(u16 addr, unsigned nelem, bool increment);
|
||||
int spilbp_transact(void *buffer, size_t size);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue