nbhw18: automatically load fpga bitstream & cleanup of code

This commit is contained in:
user 2018-03-22 14:52:27 +01:00
parent f0fb4ed9d8
commit d64b235f23
8 changed files with 211 additions and 164 deletions

View File

@ -63,6 +63,7 @@
misc@0 {
#gpio-cells = <4>;
// gpio controller, gpio number, low/high_active, default value
sd-card-enable = <&gpiofpga 65 GPIO_ACTIVE_HIGH 1>;
};
// pcie slot 0
@ -109,11 +110,9 @@
};
// sfp (mapped in fpga also as a pcie slot)
pcieslot@5 {
reset = <&gpiofpga 389 GPIO_ACTIVE_HIGH 1>;
power = <&gpiofpga 405 GPIO_ACTIVE_HIGH 0>;
wdis-out = <&gpiofpga 8197 GPIO_ACTIVE_HIGH 1>;
wdis = <&gpiofpga 8213 GPIO_ACTIVE_LOW 1>;
sfp@0 {
power = <&gpiofpga 405 GPIO_ACTIVE_HIGH 1>;
reset = <&gpiofpga 389 GPIO_ACTIVE_HIGH 0>;
};
};

2
board/nm/common/lattice/core.c Normal file → Executable file
View File

@ -66,7 +66,7 @@ extern unsigned int a_uiRowCount;
**************************************************************************/
unsigned char currentChannel;
unsigned char getCurrentChannel()
unsigned char getCurrentChannel(void)
{
return currentChannel;
}

View File

@ -54,7 +54,7 @@ unsigned int a_uiRowCount = 0;
/*********************************************************************
* here you may implement debug initializing function.
**********************************************************************/
int dbgu_init()
int dbgu_init(void)
{
return 1;
}

19
board/nm/common/lattice/hardware.h Normal file → Executable file
View File

@ -8,21 +8,30 @@
*************************************************************************/
//#define DISPLAY 1
//#define LOG_DISPLAY 1
#include <common.h>
void FPGA_START(void);
void FPGA_FINAL(void);
void FPGA_OUT(u8 b);
u8 FPGA_IN(void);
void FPGA_CS_LOW(void);
void FPGA_CS_HIGH(void);
/************************************************************************
* Hardware functions
*************************************************************************/
int SPI_init();
int SPI_final();
int SPI_init(void);
int SPI_final(void);
int wait(int ms);
/************************************************************************
* SPI transmission functions
*************************************************************************/
int TRANS_starttranx(unsigned char channel);
int TRANS_endtranx();
int TRANS_endtranx(void);
int TRANS_cstoggle(unsigned char channel);
int TRANS_trsttoggle(unsigned char toggle);
int TRANS_runClk();
int TRANS_runClk(void);
int TRANS_transmitBytes(unsigned char *trBuffer, int trCount);
int TRANS_receiveBytes(unsigned char *rcBuffer, int rcCount);
@ -55,7 +64,7 @@ int TRANS_transceive_stream(int trCount, unsigned char *trBuffer,
#ifdef DEBUG_LEVEL_1
#include "debug.h"
int dbgu_init();
int dbgu_init(void);
void dbgu_putint(int debugCode, int debugCode2);
//#define DEBUG_LEVEL_2 1
#endif

4
board/nm/common/lattice/intrface.c Normal file → Executable file
View File

@ -246,7 +246,7 @@ static int dataptr = 0;
int i = 0;
d_offset = 0;
d_currentDataSetIndex = 0;
printf("dataInit:d_isDataInput:%d\n", d_isDataInput);
if(d_isDataInput == 0)
return PROC_COMPLETE;
/********************************************************************
@ -575,9 +575,7 @@ printf("dataInit:d_isDataInput:%d\n", d_isDataInput);
{
int i = 0;
unsigned char currentByte = 0;
printf("dataRequestSet:%d\n", dataSet);
for(i = 0; i < d_tocNumber; i++){
printf("d_toc[i].ID:%d\n", d_toc[i].ID);
if(d_toc[i].ID == dataSet){
d_currentDataSetIndex = i;
break;

View File

@ -12,7 +12,7 @@
* GNU General Public License for more details.
*
*****************************************************************************/
#define DEBUG
#undef DEBUG
#include <common.h>
#include <dm.h>
#include <dm/device.h>
@ -61,6 +61,13 @@ struct nbhw_fpga_priv {
struct udevice *fpga_dev;
void tickdelay(void)
{
uint64_t curtick;
curtick = get_ticks(); /* get current timestamp */
while (get_ticks() < curtick+1); /* loop till event */
}
static inline u8 spi_read_ecp5(const struct nbhw_fpga_priv *priv)
{
int i;
@ -75,10 +82,12 @@ static inline u8 spi_read_ecp5(const struct nbhw_fpga_priv *priv)
res |= d;
dm_gpio_set_value(&priv->sck, 1);
ndelay(50);
//ndelay(50);
tickdelay();
dm_gpio_set_value(&priv->sck, 0);
ndelay(50);
//ndelay(50);
tickdelay();
}
return res;
}
@ -92,11 +101,13 @@ static inline void spi_write_ecp5(const struct nbhw_fpga_priv *priv, u8 data)
{
data_write = (data & 0x80) ? 1 : 0;
dm_gpio_set_value(&priv->sdi, data_write);
ndelay(50);
//ndelay(50);
tickdelay();
/* Read data on rising edge */
dm_gpio_set_value(&priv->sck, 1);
ndelay(50);
//ndelay(50);
tickdelay();
/* Clear clk bit and put data on the line */
dm_gpio_set_value(&priv->sck, 0);
@ -152,7 +163,7 @@ static int fpga_verify(struct nbhw_fpga_priv *priv)
} else if (signature == 0x012f) {
strcpy(fpga_type, "LFE5U-12F-6BG381I NBHW18 V2");
} else {
priv->signature = 0;
priv->signature = signature;
goto abort;
}
@ -165,7 +176,93 @@ static int fpga_verify(struct nbhw_fpga_priv *priv)
return 1;
abort:
printf(" No FPGA detected! (Signature:%x)\n", signature);
return 0;
}
#define print_out_string printf
extern unsigned int a_uiRowCount;
void printError(int code){
char Message[512];
sprintf(Message, "Error Code: %d\n\n", code);
print_out_string(Message);
switch(code){
case ERROR_INIT_ALGO:
print_out_string("Initialize algorithm file fail.\n");
break;
case ERROR_INIT_DATA:
print_out_string("Initialize data file fail.\n");
break;
case ERROR_INIT_VERSION:
print_out_string("Version not supported.\n");
break;
case ERROR_INIT_CHECKSUM:
print_out_string("Header checksum fail.\n");
break;
case ERROR_INIT_SPI:
print_out_string("Initialize SPI fail.\n");
break;
case ERROR_INIT:
print_out_string("Initialization fail.\n");
break;
case ERROR_PROC_ALGO:
print_out_string("Incorrect algorithm format.\n");
break;
case ERROR_PROC_DATA:
print_out_string("Invalid data.\n");
break;
case ERROR_PROC_HARDWARE:
print_out_string("Hardware fail.\n");
break;
case ERROR_VERIFICATION:
print_out_string("Verification fail.\n");
if(a_uiRowCount > 0)
{
sprintf(Message, "Failed on Frame %d\n",a_uiRowCount);
print_out_string(Message);
}
break;
case ERROR_IDCODE:
print_out_string("IDCODE verification fail.\n");
break;
case ERROR_USERCODE:
print_out_string("USERCODE verification fail.\n");
break;
case ERROR_SED:
print_out_string("SED CRC verification fail.\n");
break;
case ERROR_TAG:
print_out_string("TAG Memory verification fail.\n");
break;
case ERROR_LOOP_COND:
print_out_string("LOOP condition fail.\n");
break;
default:
print_out_string("Process fail.\n");
break;
}
}
static int do_fpga_lattice (struct nbhw_fpga_priv *priv, int argc,
char * const argv[])
{
int siRetCode;
siRetCode = SSPIEm_preset("", "");
siRetCode = SSPIEm(0xFFFFFFFF);
if ( siRetCode != 2 ) {
print_out_string ("\n\n");
print_out_string( "+=======+\n" );
print_out_string( "| FAIL! |\n" );
print_out_string( "+=======+\n\n" );
printError(siRetCode);
}
else {
print_out_string( "+=======+\n" );
print_out_string( "| PASS! |\n" );
print_out_string( "+=======+\n\n" );
}
return 0;
}
@ -267,51 +364,51 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat
return 1;
}
static u32 fpga_ecp5_read_status (const struct nbhw_fpga_priv *priv)
{
u32 read_status;
/* Send LSC_READ_STATUS command */
dm_gpio_set_value(&priv->ss, 0);
udelay(1);
spi_write_ecp5(priv, 0x3c /* LSC_READ_STATUS */);
spi_write_ecp5(priv, 0x00);
spi_write_ecp5(priv, 0x00);
spi_write_ecp5(priv, 0x00);
read_status = spi_read_ecp5(priv);
read_status = (read_status << 8) + spi_read_ecp5(priv);
read_status = (read_status << 8) + spi_read_ecp5(priv);
read_status = (read_status << 8) + spi_read_ecp5(priv);
dm_gpio_set_value(&priv->ss, 1);
udelay(1);
return read_status;
}
//static u32 fpga_ecp5_read_status (const struct nbhw_fpga_priv *priv)
//{
// u32 read_status;
//
// /* Send LSC_READ_STATUS command */
// dm_gpio_set_value(&priv->ss, 0);
// udelay(1);
//
// spi_write_ecp5(priv, 0x3c /* LSC_READ_STATUS */);
// spi_write_ecp5(priv, 0x00);
// spi_write_ecp5(priv, 0x00);
// spi_write_ecp5(priv, 0x00);
//
// read_status = spi_read_ecp5(priv);
// read_status = (read_status << 8) + spi_read_ecp5(priv);
// read_status = (read_status << 8) + spi_read_ecp5(priv);
// read_status = (read_status << 8) + spi_read_ecp5(priv);
//
// dm_gpio_set_value(&priv->ss, 1);
// udelay(1);
//
// return read_status;
//}
static int fpga_load_bitstream_lattice_ecp5 (const struct nbhw_fpga_priv *priv, const u8* data, int num_bytes)
{
int i;
u32 device_id;
u32 read_status;
bool device_id_ok;
put_in_prog_mode_lattice_ecp5(priv);
udelay(50000);
if (!dm_gpio_get_value(&priv->cdone)) {
printf("Error: FPGA does not signal done\n");
return -1;
}
debug("FPGA signals done\n");
return 1;
}
//static int fpga_load_bitstream_lattice_ecp5 (const struct nbhw_fpga_priv *priv, const u8* data, int num_bytes)
//{
// int i;
// u32 device_id;
// u32 read_status;
// bool device_id_ok;
//
// put_in_prog_mode_lattice_ecp5(priv);
//
// udelay(50000);
//
// if (!dm_gpio_get_value(&priv->cdone)) {
// printf("Error: FPGA does not signal done\n");
// return -1;
// }
//
// debug("FPGA signals done\n");
//
// return 1;
//}
static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv, const u8* fpgadata, u8** pStartAddr, int* pSize)
{
@ -499,7 +596,8 @@ static int fpga_boot_buffer(const struct nbhw_fpga_priv *priv, const u8* data, i
/* Write bit stream */
switch (priv->fpga_type) {
case FPGA_LATTICE_ECP5 :
res = fpga_load_bitstream_lattice_ecp5(priv, raw_bitstream, raw_num_bytes);
//res = fpga_load_bitstream_lattice_ecp5(priv, raw_bitstream, raw_num_bytes);
res = (do_fpga_lattice ((struct nbhw_fpga_priv*)priv, 0, 0) == 0) ? 1 : 0;
break;
default :
res = fpga_load_bitstream(priv, raw_bitstream, raw_num_bytes);
@ -640,7 +738,7 @@ FPGA_PRIV = priv;
static int fpga_program(struct udevice *dev, unsigned long load_addr,
unsigned long filesize)
{
int res;
int res, i;
struct nbhw_fpga_priv *priv = dev_get_priv(dev);
debug("%s\n", __func__);
@ -665,11 +763,18 @@ static int fpga_program(struct udevice *dev, unsigned long load_addr,
/* Make sure device bus works, becaus NBHW14 uses its gpios to do SPI */
setup_device_bus();
/* Verify, if FPGA is loaded successfully */
res = fpga_verify(priv);
i = 0;
do {
// try a few times, as Lattice ECP5 seems to need some time to get ready
res = fpga_verify(priv);
udelay(100000);
i++;
} while ((i<20) && (!res));
if (!res)
{
printf(" No FPGA detected! (Signature:%x)\n", priv->signature);
return -4;
}
@ -901,92 +1006,6 @@ static int do_fpga_cmd (struct nbhw_fpga_priv *priv, int argc,
return 0;
}
#define print_out_string printf
extern unsigned int a_uiRowCount;
void printError(int code){
char Message[512];
sprintf(Message, "Error Code: %d\n\n", code);
print_out_string(Message);
switch(code){
case ERROR_INIT_ALGO:
print_out_string("Initialize algorithm file fail.\n");
break;
case ERROR_INIT_DATA:
print_out_string("Initialize data file fail.\n");
break;
case ERROR_INIT_VERSION:
print_out_string("Version not supported.\n");
break;
case ERROR_INIT_CHECKSUM:
print_out_string("Header checksum fail.\n");
break;
case ERROR_INIT_SPI:
print_out_string("Initialize SPI fail.\n");
break;
case ERROR_INIT:
print_out_string("Initialization fail.\n");
break;
case ERROR_PROC_ALGO:
print_out_string("Incorrect algorithm format.\n");
break;
case ERROR_PROC_DATA:
print_out_string("Invalid data.\n");
break;
case ERROR_PROC_HARDWARE:
print_out_string("Hardware fail.\n");
break;
case ERROR_VERIFICATION:
print_out_string("Verification fail.\n");
if(a_uiRowCount > 0)
{
sprintf(Message, "Failed on Frame %d\n",a_uiRowCount);
print_out_string(Message);
}
break;
case ERROR_IDCODE:
print_out_string("IDCODE verification fail.\n");
break;
case ERROR_USERCODE:
print_out_string("USERCODE verification fail.\n");
break;
case ERROR_SED:
print_out_string("SED CRC verification fail.\n");
break;
case ERROR_TAG:
print_out_string("TAG Memory verification fail.\n");
break;
case ERROR_LOOP_COND:
print_out_string("LOOP condition fail.\n");
break;
default:
print_out_string("Process fail.\n");
break;
}
}
static int do_fpga_lattice (struct nbhw_fpga_priv *priv, int argc,
char * const argv[])
{
int siRetCode;
siRetCode = SSPIEm_preset("", "");
siRetCode = SSPIEm(0xFFFFFFFF);
if ( siRetCode != 2 ) {
print_out_string ("\n\n");
print_out_string( "+=======+\n" );
print_out_string( "| FAIL! |\n" );
print_out_string( "+=======+\n\n" );
printError(siRetCode);
}
else {
print_out_string( "+=======+\n" );
print_out_string( "| PASS! |\n" );
print_out_string( "+=======+\n\n" );
}
return 0;
}
struct fpga_cmd {
const char *cmd;
@ -1121,11 +1140,11 @@ U_BOOT_DRIVER(gpio_nbhw_fpga) = {
/* Lattice programming tool stuff -> TODO: Cleanup as soon as possible */
void FPGA_START() {
void FPGA_START(void) {
put_in_prog_mode_lattice_ecp5(FPGA_PRIV);
}
void FPGA_FINAL() {
void FPGA_FINAL(void) {
clean_up_after_programming(FPGA_PRIV);
}
@ -1133,16 +1152,16 @@ void FPGA_OUT(u8 b) {
spi_write_ecp5(FPGA_PRIV, b);
}
u8 FPGA_IN(u8 b) {
u8 FPGA_IN(void) {
return spi_read_ecp5(FPGA_PRIV);
}
void FPGA_CS_LOW()
void FPGA_CS_LOW(void)
{
dm_gpio_set_value(&FPGA_PRIV->ss, 0);
}
void FPGA_CS_HIGH()
void FPGA_CS_HIGH(void)
{
dm_gpio_set_value(&FPGA_PRIV->ss, 1);
}

View File

@ -79,8 +79,14 @@ struct pcie_slot_gpios {
struct gpio_desc clk;
};
struct sfp_gpios {
struct gpio_desc reset;
struct gpio_desc power;
};
#define PCIE_SLOT_COUNT 8
static struct pcie_slot_gpios pcie_slots[PCIE_SLOT_COUNT];
static struct sfp_gpios sfps;
static int pcie_slot_count = 0;
@ -112,6 +118,19 @@ static int request_and_set_gpio_by_name(ofnode fdt,
return 0;
}
static int add_sfp(ofnode fdt)
{
debug("%s\n", __func__);
request_and_set_gpio_by_name(fdt, "power",
&sfps.power);
request_and_set_gpio_by_name(fdt, "reset",
&sfps.reset);
return 0;
}
static int add_pcie_slot(ofnode fdt)
{
debug("%s\n", __func__);
@ -324,10 +343,13 @@ int nbhw_fpga_configure(void)
configure_misc(subnode);
}
if (!strncmp("pcieslot", name, 4)) {
if (!strncmp("pcieslot", name, 8)) {
add_pcie_slot(subnode);
}
if (!strncmp("sfp", name, 3)) {
add_sfp(subnode);
}
}
if (configure_leds())

View File

@ -31,7 +31,7 @@
as soon as we have the register definition for NBHW18 V2
*/
#define OUTPUT1 (0x0008)
//#define OUTPUT1 (0x0008)
#define PCIE_RESET (0x0030)
#define SMI_CTRL (0x0042)
@ -270,14 +270,14 @@ void configure_mvswitch(void)
unsigned short value;
/* Enable I2C on extension module */
FPGA_REG(OUTPUT1) = OUTPUT1_EN_I2C_EXT_N_MASK;
//FPGA_REG(OUTPUT1) = OUTPUT1_EN_I2C_EXT_N_MASK;
udelay(200000); /* 200 ms */
/* Check if external switch is there */
if (!i2c_probe(0x57)) {
puts("Extension detected: enable 5V\n");
FPGA_REG(OUTPUT1) |= OUTPUT1_EN_5V0_EXT_MASK;
//FPGA_REG(OUTPUT1) |= OUTPUT1_EN_5V0_EXT_MASK;
udelay(100000);
}