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

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 currentChannel;
unsigned char getCurrentChannel() unsigned char getCurrentChannel(void)
{ {
return currentChannel; return currentChannel;
} }

View File

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

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

@ -8,21 +8,30 @@
*************************************************************************/ *************************************************************************/
//#define DISPLAY 1 //#define DISPLAY 1
//#define LOG_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 * Hardware functions
*************************************************************************/ *************************************************************************/
int SPI_init(); int SPI_init(void);
int SPI_final(); int SPI_final(void);
int wait(int ms); int wait(int ms);
/************************************************************************ /************************************************************************
* SPI transmission functions * SPI transmission functions
*************************************************************************/ *************************************************************************/
int TRANS_starttranx(unsigned char channel); int TRANS_starttranx(unsigned char channel);
int TRANS_endtranx(); int TRANS_endtranx(void);
int TRANS_cstoggle(unsigned char channel); int TRANS_cstoggle(unsigned char channel);
int TRANS_trsttoggle(unsigned char toggle); int TRANS_trsttoggle(unsigned char toggle);
int TRANS_runClk(); int TRANS_runClk(void);
int TRANS_transmitBytes(unsigned char *trBuffer, int trCount); int TRANS_transmitBytes(unsigned char *trBuffer, int trCount);
int TRANS_receiveBytes(unsigned char *rcBuffer, int rcCount); 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 #ifdef DEBUG_LEVEL_1
#include "debug.h" #include "debug.h"
int dbgu_init(); int dbgu_init(void);
void dbgu_putint(int debugCode, int debugCode2); void dbgu_putint(int debugCode, int debugCode2);
//#define DEBUG_LEVEL_2 1 //#define DEBUG_LEVEL_2 1
#endif #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; int i = 0;
d_offset = 0; d_offset = 0;
d_currentDataSetIndex = 0; d_currentDataSetIndex = 0;
printf("dataInit:d_isDataInput:%d\n", d_isDataInput);
if(d_isDataInput == 0) if(d_isDataInput == 0)
return PROC_COMPLETE; return PROC_COMPLETE;
/******************************************************************** /********************************************************************
@ -575,9 +575,7 @@ printf("dataInit:d_isDataInput:%d\n", d_isDataInput);
{ {
int i = 0; int i = 0;
unsigned char currentByte = 0; unsigned char currentByte = 0;
printf("dataRequestSet:%d\n", dataSet);
for(i = 0; i < d_tocNumber; i++){ for(i = 0; i < d_tocNumber; i++){
printf("d_toc[i].ID:%d\n", d_toc[i].ID);
if(d_toc[i].ID == dataSet){ if(d_toc[i].ID == dataSet){
d_currentDataSetIndex = i; d_currentDataSetIndex = i;
break; break;

View File

@ -12,7 +12,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
*****************************************************************************/ *****************************************************************************/
#define DEBUG #undef DEBUG
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <dm/device.h> #include <dm/device.h>
@ -61,6 +61,13 @@ struct nbhw_fpga_priv {
struct udevice *fpga_dev; 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) static inline u8 spi_read_ecp5(const struct nbhw_fpga_priv *priv)
{ {
int i; int i;
@ -75,10 +82,12 @@ static inline u8 spi_read_ecp5(const struct nbhw_fpga_priv *priv)
res |= d; res |= d;
dm_gpio_set_value(&priv->sck, 1); dm_gpio_set_value(&priv->sck, 1);
ndelay(50); //ndelay(50);
tickdelay();
dm_gpio_set_value(&priv->sck, 0); dm_gpio_set_value(&priv->sck, 0);
ndelay(50); //ndelay(50);
tickdelay();
} }
return res; 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; data_write = (data & 0x80) ? 1 : 0;
dm_gpio_set_value(&priv->sdi, data_write); dm_gpio_set_value(&priv->sdi, data_write);
ndelay(50); //ndelay(50);
tickdelay();
/* Read data on rising edge */ /* Read data on rising edge */
dm_gpio_set_value(&priv->sck, 1); dm_gpio_set_value(&priv->sck, 1);
ndelay(50); //ndelay(50);
tickdelay();
/* Clear clk bit and put data on the line */ /* Clear clk bit and put data on the line */
dm_gpio_set_value(&priv->sck, 0); dm_gpio_set_value(&priv->sck, 0);
@ -152,7 +163,7 @@ static int fpga_verify(struct nbhw_fpga_priv *priv)
} else if (signature == 0x012f) { } else if (signature == 0x012f) {
strcpy(fpga_type, "LFE5U-12F-6BG381I NBHW18 V2"); strcpy(fpga_type, "LFE5U-12F-6BG381I NBHW18 V2");
} else { } else {
priv->signature = 0; priv->signature = signature;
goto abort; goto abort;
} }
@ -165,7 +176,93 @@ static int fpga_verify(struct nbhw_fpga_priv *priv)
return 1; return 1;
abort: 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; return 0;
} }
@ -267,51 +364,51 @@ static int fpga_load_bitstream (const struct nbhw_fpga_priv *priv, const u8* dat
return 1; return 1;
} }
static u32 fpga_ecp5_read_status (const struct nbhw_fpga_priv *priv) //static u32 fpga_ecp5_read_status (const struct nbhw_fpga_priv *priv)
{ //{
u32 read_status; // u32 read_status;
//
/* Send LSC_READ_STATUS command */ // /* Send LSC_READ_STATUS command */
dm_gpio_set_value(&priv->ss, 0); // dm_gpio_set_value(&priv->ss, 0);
udelay(1); // udelay(1);
//
spi_write_ecp5(priv, 0x3c /* LSC_READ_STATUS */); // spi_write_ecp5(priv, 0x3c /* LSC_READ_STATUS */);
spi_write_ecp5(priv, 0x00); // spi_write_ecp5(priv, 0x00);
spi_write_ecp5(priv, 0x00); // spi_write_ecp5(priv, 0x00);
spi_write_ecp5(priv, 0x00); // spi_write_ecp5(priv, 0x00);
//
read_status = spi_read_ecp5(priv); // 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); // 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); // dm_gpio_set_value(&priv->ss, 1);
udelay(1); // udelay(1);
//
return read_status; // return read_status;
} //}
static int fpga_load_bitstream_lattice_ecp5 (const struct nbhw_fpga_priv *priv, const u8* data, int num_bytes) //static int fpga_load_bitstream_lattice_ecp5 (const struct nbhw_fpga_priv *priv, const u8* data, int num_bytes)
{ //{
int i; // int i;
u32 device_id; // u32 device_id;
u32 read_status; // u32 read_status;
bool device_id_ok; // bool device_id_ok;
//
put_in_prog_mode_lattice_ecp5(priv); // put_in_prog_mode_lattice_ecp5(priv);
//
udelay(50000); // udelay(50000);
//
if (!dm_gpio_get_value(&priv->cdone)) { // if (!dm_gpio_get_value(&priv->cdone)) {
printf("Error: FPGA does not signal done\n"); // printf("Error: FPGA does not signal done\n");
return -1; // return -1;
} // }
//
debug("FPGA signals done\n"); // debug("FPGA signals done\n");
//
return 1; // return 1;
} //}
static int fpga_check_bitstream_lattice(const struct nbhw_fpga_priv *priv, const u8* fpgadata, u8** pStartAddr, int* pSize) 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 */ /* Write bit stream */
switch (priv->fpga_type) { switch (priv->fpga_type) {
case FPGA_LATTICE_ECP5 : 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; break;
default : default :
res = fpga_load_bitstream(priv, raw_bitstream, raw_num_bytes); 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, static int fpga_program(struct udevice *dev, unsigned long load_addr,
unsigned long filesize) unsigned long filesize)
{ {
int res; int res, i;
struct nbhw_fpga_priv *priv = dev_get_priv(dev); struct nbhw_fpga_priv *priv = dev_get_priv(dev);
debug("%s\n", __func__); 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 */ /* Make sure device bus works, becaus NBHW14 uses its gpios to do SPI */
setup_device_bus(); setup_device_bus();
/* Verify, if FPGA is loaded successfully */ /* Verify, if FPGA is loaded successfully */
i = 0;
do {
// try a few times, as Lattice ECP5 seems to need some time to get ready
res = fpga_verify(priv); res = fpga_verify(priv);
udelay(100000);
i++;
} while ((i<20) && (!res));
if (!res) if (!res)
{ {
printf(" No FPGA detected! (Signature:%x)\n", priv->signature);
return -4; return -4;
} }
@ -901,92 +1006,6 @@ static int do_fpga_cmd (struct nbhw_fpga_priv *priv, int argc,
return 0; 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 { struct fpga_cmd {
const char *cmd; const char *cmd;
@ -1121,11 +1140,11 @@ U_BOOT_DRIVER(gpio_nbhw_fpga) = {
/* Lattice programming tool stuff -> TODO: Cleanup as soon as possible */ /* 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); put_in_prog_mode_lattice_ecp5(FPGA_PRIV);
} }
void FPGA_FINAL() { void FPGA_FINAL(void) {
clean_up_after_programming(FPGA_PRIV); clean_up_after_programming(FPGA_PRIV);
} }
@ -1133,16 +1152,16 @@ void FPGA_OUT(u8 b) {
spi_write_ecp5(FPGA_PRIV, b); spi_write_ecp5(FPGA_PRIV, b);
} }
u8 FPGA_IN(u8 b) { u8 FPGA_IN(void) {
return spi_read_ecp5(FPGA_PRIV); return spi_read_ecp5(FPGA_PRIV);
} }
void FPGA_CS_LOW() void FPGA_CS_LOW(void)
{ {
dm_gpio_set_value(&FPGA_PRIV->ss, 0); 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); dm_gpio_set_value(&FPGA_PRIV->ss, 1);
} }

View File

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

View File

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