News:

Attention: For security reasons,please choose a user name *different* from your login name.
Also make sure to choose a secure password and change it regularly.

Main Menu

flashcp on 32MB QSPI

Started by crc, May 29, 2014, 06:14:32 PM

Previous topic - Next topic

crc

I am using the Gigazee module with the 32MB Winbond QSPI and am trying to update the qspi partitions using flashcp. I have setup u-boot, kernel and devicetree to use a 15MB ramdisk. Unfortunately, once booted, the mtd partitions are referencing the upper 16MB of qspi instead of the lower where everything is actually stored when programmed with jtag. Thus when I reboot I am still using the jtag flashed data instead of the data flashed with flashcp. If I use the default size instead of 15MB everything works fine. Also, works great with 15MB ramdisk on a zedboard.

Any help on how to have the mtd partitions reference the correct locations in qspi when using a 15MB ramdisk?

Oleksandr Kiyenko

Hello,
Xilinx controller/tools have known limitations about QSPI Flash access. Most tools works correctly only with low 16M. You can found a lot of application notes like http://www.xilinx.com/support/answers/47500.htm
Also there was a problem with old QSPI driver in linux. Which linux kernel version are you use ?
I recommend you to limit ramdisk and move part of your system to onboard eMMC card. If you 100% sure that you want to use large ramdisk we can try together to found solution, but this solution will hightly depend on kernel/tools version you use.

Best regards
Oleksandr Kiyenko

crc

#2
I am using 3.12 from the Xilinx git repo (at tag xilinx-v2013.4-trd). I would use 3.13 but that has kernel panic when it loads and I haven't had time to figure out why yet. I am using the CR module that does not have the eMMC card. I'm 100% sure on using a large ramdisk.

My devicetree is setup as follows:
fsbl-uboot:      reg = <0x0 0x450000>;
linux:               reg = <0x450000 0x500000>;
device-tree:   reg = <0x950000 0x20000>;
rootfs:              reg = <0x970000 0xF00000>;
         
Everything works when u-boot is setup as follows:
kernel_addr=0x2000000
kernel_size=0x500000
kernel_offset=0x450000
devicetree_addr=0x2A00000
devicetree_size=0x20000
devicetree_offset=0x950000
ramdisk_addr=0x3000000
ramdisk_size=0x5E0000
ramdisk_offset=0x970000


It doesn't work when I change to the following in u-boot:
ramdisk_size=0xF00000


With ramdisk_size=0xF00000 my mtd partitions for some reason point to the following. Which is located in the upper 16MB even though they are defined as stated above.
fsbl-uboot:      reg = <0x1000000 0x450000>;
linux:               reg = <0x1450000 0x500000>;
device-tree:   reg = <0x1950000 0x20000>;
rootfs:             reg = <0x1970000 0xF00000>;

crc

Solution is to modify the file m25p80.c to match the following:
(see the post on the xilinx forum forums.xilinx.com/t5/Embedded-Linux/flashcp-with-32MB-QSPI/td-p/468226/highlight/false/page/2)

static int m25p_probe(struct spi_device *spi)
{
...
  if (info->addr_width)
    flash->addr_width = info->addr_width;
  else if (flash->mtd.size > 0x1000000) {
    np = of_get_next_parent(spi->dev.of_node);
    if (of_property_match_string(np, "compatible",
             "xlnx,zynq-qspi-1.0") >= 0) {
      int status;
      flash->addr_width = 3;
      set_4byte(flash, info->jedec_id, 0);
      status = read_ear(flash);
      if (status < 0)
        dev_warn(&spi->dev, "failed to read ear reg\n");
      else
        flash->curbank = status & EAR_SEGMENT_MASK;
    } else {
...
}

static int read_ear(struct m25p *flash)
{
...
  if (JEDEC_MFR(flash->jedec_id) == CFI_MFR_AMD)
    code = OPCODE_BRRD;
  else if (JEDEC_MFR(flash->jedec_id) == CFI_MFR_ST)
    code = OPCODE_RDEAR;
  else if (JEDEC_MFR(flash->jedec_id) == 0xEF) //<-----Missing?
    code = OPCODE_RDEAR;                       //<-----Missing?
  else
    return -EINVAL;
...
}

static int write_ear(struct m25p *flash, u32 addr)
{
...
  if (JEDEC_MFR(flash->jedec_id) == 0x01)
    flash->command[0] = OPCODE_BRWR;
  if (JEDEC_MFR(flash->jedec_id) == 0x20) {
    write_enable(flash);
    flash->command[0] = OPCODE_WREAR;
  }
  if (JEDEC_MFR(flash->jedec_id) == 0xEF) { //<-----Missing?
    write_enable(flash);                    //<-----Missing?
    flash->command[0] = OPCODE_WREAR;       //<-----Missing?
  }
  // No error if not JEDEC_MFR is not recognized!
...

}


spoilerhead

Just ran into the same issue using petalinux. Will this patch be incorporated into the trenz BSP?

dieter

Antti Lukats

BSP can not include "kernel patches"

so in the case petalinux 2014.3 does still have the issue a small kernel patch would be needed.

But we can not include patches as part of BSP, any kernel patches must be delivered separately from BSP

spoilerhead

Thank you for the quick reply.

I just assumed, that it would be possible in petalinux, as it's afaik based on yocto, which includes the possibility.

Antti Lukats

applying patches yes possible, but I do not think that the BSP package generation of petalinux would include the patches.

if petalinx BSPs would include kernel patches, then installing BSP would each time patch the kernel what could create a mess