From d64b235f23e254b2ac4a3d3854469732fe02291b Mon Sep 17 00:00:00 2001 From: user Date: Thu, 22 Mar 2018 14:52:27 +0100 Subject: [PATCH] nbhw18: automatically load fpga bitstream & cleanup of code --- arch/arm/dts/armada-385-nbhw18-common.dtsi | 9 +- board/nm/common/lattice/core.c | 2 +- board/nm/common/lattice/hardware.c | 2 +- board/nm/common/lattice/hardware.h | 19 +- board/nm/common/lattice/intrface.c | 4 +- board/nm/common/nbhw_fpga_gpio.c | 309 +++++++++++---------- board/nm/nbhw18_v2/nbhw_fpga_config.c | 24 +- board/nm/nbhw18_v2/nbhw_mvswitch.c | 6 +- 8 files changed, 211 insertions(+), 164 deletions(-) mode change 100644 => 100755 board/nm/common/lattice/core.c mode change 100644 => 100755 board/nm/common/lattice/hardware.h mode change 100644 => 100755 board/nm/common/lattice/intrface.c diff --git a/arch/arm/dts/armada-385-nbhw18-common.dtsi b/arch/arm/dts/armada-385-nbhw18-common.dtsi index f155873e85..3d031ceb2e 100755 --- a/arch/arm/dts/armada-385-nbhw18-common.dtsi +++ b/arch/arm/dts/armada-385-nbhw18-common.dtsi @@ -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>; }; }; diff --git a/board/nm/common/lattice/core.c b/board/nm/common/lattice/core.c old mode 100644 new mode 100755 index 6077be310d..0c25a0574f --- a/board/nm/common/lattice/core.c +++ b/board/nm/common/lattice/core.c @@ -66,7 +66,7 @@ extern unsigned int a_uiRowCount; **************************************************************************/ unsigned char currentChannel; -unsigned char getCurrentChannel() +unsigned char getCurrentChannel(void) { return currentChannel; } diff --git a/board/nm/common/lattice/hardware.c b/board/nm/common/lattice/hardware.c index 30110a03b4..94fb61965e 100755 --- a/board/nm/common/lattice/hardware.c +++ b/board/nm/common/lattice/hardware.c @@ -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; } diff --git a/board/nm/common/lattice/hardware.h b/board/nm/common/lattice/hardware.h old mode 100644 new mode 100755 index a19d15ffdb..f0ae0e3642 --- a/board/nm/common/lattice/hardware.h +++ b/board/nm/common/lattice/hardware.h @@ -8,21 +8,30 @@ *************************************************************************/ //#define DISPLAY 1 //#define LOG_DISPLAY 1 +#include + +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 diff --git a/board/nm/common/lattice/intrface.c b/board/nm/common/lattice/intrface.c old mode 100644 new mode 100755 index d837b28c73..7e3368763e --- a/board/nm/common/lattice/intrface.c +++ b/board/nm/common/lattice/intrface.c @@ -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; diff --git a/board/nm/common/nbhw_fpga_gpio.c b/board/nm/common/nbhw_fpga_gpio.c index 52a6ea522c..dab73ca704 100755 --- a/board/nm/common/nbhw_fpga_gpio.c +++ b/board/nm/common/nbhw_fpga_gpio.c @@ -12,7 +12,7 @@ * GNU General Public License for more details. * *****************************************************************************/ -#define DEBUG +#undef DEBUG #include #include #include @@ -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); } diff --git a/board/nm/nbhw18_v2/nbhw_fpga_config.c b/board/nm/nbhw18_v2/nbhw_fpga_config.c index 31b6ddd1ec..d3c85558bb 100755 --- a/board/nm/nbhw18_v2/nbhw_fpga_config.c +++ b/board/nm/nbhw18_v2/nbhw_fpga_config.c @@ -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()) diff --git a/board/nm/nbhw18_v2/nbhw_mvswitch.c b/board/nm/nbhw18_v2/nbhw_mvswitch.c index f50b9ebad1..0fb6f56b01 100755 --- a/board/nm/nbhw18_v2/nbhw_mvswitch.c +++ b/board/nm/nbhw18_v2/nbhw_mvswitch.c @@ -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); }