[U-Boot-Users] FPGA loading question

Hi All, I've got a Spartan3E fpga I'm trying to program serially with a bin file. Is there any similar driver available to so this? I'm not sure if this is better done as a driver with embedded binary or as part of a hust script but the bin file embedded in the u-boot source. (I'm not sure if the latter is possible).
Thanks.

Hi <no forename>,
On Wednesday 26 September 2007 22:48, E Robertson wrote:
Hi All, I've got a Spartan3E fpga I'm trying to program serially with a bin file.
fine.
Is there any similar driver available to so this?
You can use the U-Boot fpga subsystem. See common/cmd_fpga.c You have to write same board specific code to access the FPGA's serial interface.
I'm not sure if this is better done as a driver with embedded binary or as part of a hust script but the bin file embedded in the u-boot source. (I'm not sure if the latter is possible).
Nearly everything is possible:-) Even embedded FPGA binaries are used with some U-Boot'supported boards (we have some of these), I must say that's not best practice - and we will stop doing this:-). Since FPGA's are getting bigger and bigger you end up with large binary images in the U-Boot sourcetree.
I suggest to write the binary FPGA images in a separate flash section. You can make the FPGA subsystem to automatically boot the FPGA by setting an environment variable to the image's baseaddress or you can start the boot process from the command line ...
What kind of CPU are you using? Please note that 4xx U-Boot ports have the cache disabled. Without cache booting a Spartan 3E in SS-mode may take very very :-(
Matthias

Hi Matthias,
On Thursday 27 September 2007, Matthias Fuchs wrote:
What kind of CPU are you using? Please note that 4xx U-Boot ports have the cache disabled. Without cache booting a Spartan 3E in SS-mode may take very very :-(
Only 44x have cache disabled. 40x has icache enabled.
BTW: I'm still waiting for the patch to enable the cache on 44x systems... ;)
Viele Grüße, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

On 9/27/07, Stefan Roese sr@denx.de wrote:
Hi Matthias,
On Thursday 27 September 2007, Matthias Fuchs wrote:
What kind of CPU are you using? Please note that 4xx U-Boot ports have the cache disabled. Without cache booting a Spartan 3E in SS-mode may take very very :-(
Only 44x have cache disabled. 40x has icache enabled.
BTW: I'm still waiting for the patch to enable the cache on 44x systems... ;)
Viele Grüße, Stefan
I'm using an NXP ARM9 'A404 and can disable cache on my platform. Due to my hardware fool-up, I'll have to use a bit banging method. I'm also concern about loading error and recovery and I'm considering instead to do the programming in the kernel. If there is a problem for some reason and the FPGA needs to be reloaded, I'll have to do it in the kernel anyway. I'm not sure about embedding a bin file in the kernel driver either but It's worth pursuing.

E Robertson wrote:
On 9/27/07, Stefan Roese sr@denx.de wrote:
Hi Matthias,
On Thursday 27 September 2007, Matthias Fuchs wrote:
What kind of CPU are you using? Please note that 4xx U-Boot ports have the cache disabled. Without cache booting a Spartan 3E in SS-mode may take very very :-(
Only 44x have cache disabled. 40x has icache enabled.
BTW: I'm still waiting for the patch to enable the cache on 44x systems... ;)
Viele Grüße, Stefan
I'm using an NXP ARM9 'A404 and can disable cache on my platform. Due to my hardware fool-up, I'll have to use a bit banging method. I'm also concern about loading error and recovery and I'm considering instead to do the programming in the kernel. If there is a problem for some reason and the FPGA needs to be reloaded, I'll have to do it in the kernel anyway. I'm not sure about embedding a bin file in the kernel driver either but It's worth pursuing.
If your design can wait until Linux is booted before programming the FPGA, you have a world of possibilities available. In my designs, I have a simple char driver with a 'write' method that bit-bangs the image in. This way you can keep your image as a file in the file system and can add whatever encryption, wrapper or whatever your heart desires. It makes trying different FPGA images a breeze.
regards, Ben

On 9/27/07, Ben Warren bwarren@qstreams.com wrote:
E Robertson wrote:
On 9/27/07, Stefan Roese sr@denx.de wrote:
Hi Matthias,
On Thursday 27 September 2007, Matthias Fuchs wrote:
What kind of CPU are you using? Please note that 4xx U-Boot ports have the cache disabled. Without cache booting a Spartan 3E in SS-mode may take very very :-(
Only 44x have cache disabled. 40x has icache enabled.
BTW: I'm still waiting for the patch to enable the cache on 44x systems... ;)
Viele Grüße, Stefan
I'm using an NXP ARM9 'A404 and can disable cache on my platform. Due to my hardware fool-up, I'll have to use a bit banging method. I'm also concern about loading error and recovery and I'm considering instead to do the programming in the kernel. If there is a problem for some reason and the FPGA needs to be reloaded, I'll have to do it in the kernel anyway. I'm not sure about embedding a bin file in the kernel driver either but It's worth pursuing.
If your design can wait until Linux is booted before programming the FPGA, you have a world of possibilities available. In my designs, I have a simple char driver with a 'write' method that bit-bangs the image in. This way you can keep your image as a file in the file system and can add whatever encryption, wrapper or whatever your heart desires. It makes trying different FPGA images a breeze.
I'm actually in the middle of doing that with a simple char device driver. I have'n't got to the bit banging write part yet but I'll appreciate a code snip that actually parses the file for the bits. I'm assuming it'll be some sort of shift right for a char read increment or some sort of XOR operation. I haven't thought through that part yet but is that how is normally done?

E Robertson wrote:
On 9/27/07, Ben Warren bwarren@qstreams.com wrote:
E Robertson wrote:
On 9/27/07, Stefan Roese sr@denx.de wrote:
Hi Matthias,
On Thursday 27 September 2007, Matthias Fuchs wrote:
What kind of CPU are you using? Please note that 4xx U-Boot ports have the cache disabled. Without cache booting a Spartan 3E in SS-mode may take very very :-(
Only 44x have cache disabled. 40x has icache enabled.
BTW: I'm still waiting for the patch to enable the cache on 44x systems... ;)
Viele Grüße, Stefan
I'm using an NXP ARM9 'A404 and can disable cache on my platform. Due to my hardware fool-up, I'll have to use a bit banging method. I'm also concern about loading error and recovery and I'm considering instead to do the programming in the kernel. If there is a problem for some reason and the FPGA needs to be reloaded, I'll have to do it in the kernel anyway. I'm not sure about embedding a bin file in the kernel driver either but It's worth pursuing.
If your design can wait until Linux is booted before programming the FPGA, you have a world of possibilities available. In my designs, I have a simple char driver with a 'write' method that bit-bangs the image in. This way you can keep your image as a file in the file system and can add whatever encryption, wrapper or whatever your heart desires. It makes trying different FPGA images a breeze.
I'm actually in the middle of doing that with a simple char device driver. I have'n't got to the bit banging write part yet but I'll appreciate a code snip that actually parses the file for the bits. I'm assuming it'll be some sort of shift right for a char read increment or some sort of XOR operation. I haven't thought through that part yet but is that how is normally done?
/*** Here's my implementation. I'm sure it could be much better, but it seems to work. Note that all the programming bits are routed through a CPLD, that's what all the 'cpld*' function calls are for. We use this on a Virtex II, but Spartan's probably the same. The main structure of the write function is lifted by Rubini LDD3. I don't really have time to genericize it for you, but please feel free to ask questions/make suggestions for improvement. ***/
ssize_t fpga_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { int i,j; unsigned char *page_ptr; struct fpga_dev *dev = filp->private_data; u8 index = dev->index; u16 val; int rc = 0;
if (!(page_ptr = (unsigned char *)__get_free_page(GFP_KERNEL))) return -ENOMEM; if (copy_from_user(page_ptr, buf, count)) rc = -EFAULT;
/* First page of data, we set up the programming environment */ if (*f_pos == 0) { /* First, enable FPGA programming */ cpld_fpga_prog_enable(1);
/* Next, driver nPROG low for 300 ns */ cpld_fpga_write_prog(index, 0); ndelay(300); cpld_fpga_write_prog(index, 1); i = 1000; while (!cpld_fpga_check_init(index) && --i) {;} if (count <= 0) { printk(KERN_ALERT "fpga_write: timed out waiting \n"); return -EFAULT; } } /* Process a byte at a time */ for (i=0;i<count;i++) { for (j=7;j>=0;j--) { /* Shift each bit through */ if (page_ptr[i] & (1 << j)) cpld_fpga_write_data(index, 1); else cpld_fpga_write_data(index, 0); } }
if (cpld_fpga_check_done(index) != 0) { val = (u16)readFpgaReg(dev->virtAddr + FPGA_ADDR_REV_DBG/2); printk(KERN_INFO "FPGA%d loaded with version 0x%02x\n", index, val & 0xff); } if (page_ptr) free_page((u32)page_ptr); *f_pos += count; return count; }
/*** Here's the code from my CPLD driver, that writes the various control bits (FPGA_DONE, FPGA_PROG, FPGA_DONE, FPGA_INIT) that are memory mapped into a CPLD register. We have 2 FPGAs, that's what the device index is for: ***/
u8 cpld_fpga_check_init(u8 device) { return (readCpldReg(device == 0 ? &cpld_device->regs->clFpgaStat : &cpld_device->regs->liFpgaStat) & FPGA_INIT); }
EXPORT_SYMBOL(cpld_fpga_check_init);
u8 cpld_fpga_check_done(u8 device) { return (readCpldReg(device == 0 ? &cpld_device->regs->clFpgaStat : &cpld_device->regs->liFpgaStat) & FPGA_DONE); }
EXPORT_SYMBOL(cpld_fpga_check_done);
int cpld_fpga_write_prog(u8 device, u8 enable) { u16 *addr = (device == 0 ? &cpld_device->regs->clFpgaCtrl : &cpld_device->regs->liFpgaCtrl); writeCpldRegRaw(addr, enable ? FPGA_PROG : 0); return 0; }
EXPORT_SYMBOL(cpld_fpga_write_prog);
int cpld_fpga_write_clock(u8 device, u8 enable) { u16 *addr = (device == 0 ? &cpld_device->regs->clFpgaCtrl : &cpld_device->regs->liFpgaCtrl); writeCpldReg(addr, enable ? FPGA_CLK : ~FPGA_CLK, FPGA_CLK); return 0; }
EXPORT_SYMBOL(cpld_fpga_write_clock);
int cpld_fpga_write_data(u8 device, u8 bit) { u16 *addr = (device == 0 ? &cpld_device->regs->clFpgaCtrl : &cpld_device->regs->liFpgaCtrl); /* Write data & low clock together */ u16 val = bit ? FPGA_PROG | FPGA_DOUT : FPGA_PROG; writeCpldRegRaw(addr, val); /* Drive the clock high */ val |= FPGA_CLK; writeCpldRegRaw(addr, val); return 0; }
EXPORT_SYMBOL(cpld_fpga_write_data)
regards, Ben
participants (4)
-
Ben Warren
-
E Robertson
-
Matthias Fuchs
-
Stefan Roese