cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
gcwang
Observer
Observer
14,683 Views
Registered: ‎07-10-2012

Why flashcp can not control QSPI flash!

My linux is 3.3.0 from http://git.xilinx.com and i found the driver of QSPI to be located at  /driver/spi/spi-xilinx-qps.c.

The flash is s25fl256s1 of spansion. My dts file about qspi is follow.

 

qspi0: spi@e000d000 {
   compatible = "xlnx,ps7-qspi-1.00.a";
   reg = <0xE000D000 0x1000>;
   interrupts = <0 19 0>;
   interrupt-parent = <&gic>;
   speed-hz = <200000000>;
   bus-num = <1>;
   num-chip-select = <1>;
   #address-cells = <1>;
   #size-cells = <0>;
   is-dual = <0>;
   flash@0 {
   compatible = "s25fl256s1";
   reg = <0x0>;
   spi-max-frequency = <50000000>;
   #address-cells = <1>;
   #size-cells = <1>;
   partition@qspi-fsbl {
    label = "qspi-fsbl";
    reg = <0x0 0x80000>;
    };
   partition@qspi-u-boot {
    label = "qspi-u-boot";
    reg = <0x80000 0x80000>;
    };
   partition@qspi-linux {
    label = "qspi-linux";
    reg = <0x100000 0x500000>;
    };
   partition@qspi-device-tree {
    label = "qspi-device-tree";
    reg = <0x600000 0x20000>;
    };
   partition@qspi-user {
    label = "qspi-user";
    reg = <0x620000 0xE0000>;
    };
   partition@qspi-scratch {
    label = "qspi-scratch";
    reg = <0x700000 0x100000>;
    };
   partition@qspi-rootfs {
    label = "qspi-rootfs";
    reg = <0x800000 0x800000>;
    };
   };

 

The linux boot information is follow:

 

m25p80 spi1.0: s25fl256s1 (32768 Kbytes)                                                                                           
5 ofpart partitions found on MTD device spi1.0                                                                                     
Creating 5 MTD partitions on "spi1.0":                                                                                             
0x000000000000-0x000000500000 : "qspi-boot"                                                                                         
0x000000500000-0x0000007c0000 : "qspi-linux"
0x0000007c0000-0x000000800000 : "qspi-device-tree"
0x000000800000-0x000000c00000 : "qspi-rootfs"
0x000000c00000-0x000001000000 : "qspi-user"                                                                                        
xqspips e000d000.spi: at 0xE000D000 mapped to 0xE0862000, irq=51    

 

mnt # flashcp -v ramdisk8M.image.gz  /dev/mtd4
Erasing blocks: 51/51 (100%)
Writing data: 3257k/0k (100%))
Verifying data: 10k/0k (3257%)File does not seem to match flash data. First mismatch at 0x00000000-0x00002800

 

The flashcp command seemed not work well and i read the mtdblock use "sf read" command in u-boot comfirm that  write unsuccessfully.

I don't know where is wrong, have the driver of spi-xilinx-qps.c some problems?

Can anyone give me some suggest?Thank!

 

 

0 Kudos
12 Replies
gcwang
Observer
Observer
14,682 Views
Registered: ‎07-10-2012

MY new dts file about QSPI is follows:
qspi0: spi@e000d000 {
compatible = "xlnx,ps7-qspi-1.00.a";
reg = <0xE000D000 0x1000>;
interrupts = <0 19 0>;
interrupt-parent = <&gic>;
speed-hz = <200000000>;
bus-num = <1>;
num-chip-select = <1>;
#address-cells = <1>;
#size-cells = <0>;
is-dual = <0>;
flash@0 {
compatible = "s25fl256s1";
reg = <0x0>;
spi-max-frequency = <50000000>;
#address-cells = <1>;
#size-cells = <1>;
partition@boot {
label = "qspi-boot";
reg = <0x0 0x500000>;
};
partition@qspi-linux {
label = "qspi-linux";
reg = <0x500000 0x2c0000>;
};
partition@qspi-device-tree {
label = "qspi-device-tree";
reg = <0x7c0000 0x40000>;
};
partition@qspi-rootfs {
label = "qspi-rootfs";
reg = <0x800000 0x400000>;
};
partition@qspi-user {
label = "qspi-user";
reg = <0xc00000 0x400000>;
};
/*partition@qspi-fsbl {
label = "qspi-fsbl";
reg = <0x0 0x80000>;
};
partition@qspi-u-boot {
label = "qspi-u-boot";
reg = <0x80000 0x80000>;
};
partition@qspi-linux {
label = "qspi-linux";
reg = <0x100000 0x500000>;
};
partition@qspi-device-tree {
label = "qspi-device-tree";
reg = <0x600000 0x20000>;
};
partition@qspi-user {
label = "qspi-user";
reg = <0x620000 0xE0000>;
};
partition@qspi-scratch {
label = "qspi-scratch";
reg = <0x700000 0x100000>;
};
partition@qspi-rootfs {
label = "qspi-rootfs";
reg = <0x800000 0x800000>;
}; */
};
0 Kudos
gcwang
Observer
Observer
14,677 Views
Registered: ‎07-10-2012

http://wiki.xilinx.com/zc702-linux

 

Copy the images (FSBL/u-boot, Linux kernel, the device tree, and the ramdisk) from the SD card to the QSPI flash memory partitions. The flashcp command erases the flash, writes it, and verifies it. After the following command are completed, the board can be booted from QSPI flash memory after setting the boot mode jumpers.

zynq> flashcp -v BOOT.BIN /dev/mtd0
zynq> flashcp -v zImage /dev/mtd2
zynq> flashcp -v devicetree.dtb /dev/mtd3
zynq> flashcp -v ramdisk8M.image.gz /dev/mtd6

The "flashcp" tool can not write /dev/mtdx correctly!  

0 Kudos
linnj
Xilinx Employee
Xilinx Employee
14,655 Views
Registered: ‎09-10-2008

Hi,

 

It's not clear to me in the last post what you are saying, whether it's working or not, but I'm assuming it's not working.

 

If not, then what does the boot log show for qspi, can you also cat /proc/mtd to see what partitions it's showing.

 

Thanks.

0 Kudos
linnj
Xilinx Employee
Xilinx Employee
14,653 Views
Registered: ‎09-10-2008

I now see the boot log that you included. Is this running on a Xilinx board (ZC702) or on your own board?

Thanks.
0 Kudos
gcwang
Observer
Observer
14,645 Views
Registered: ‎07-10-2012

MTD info:

 

/ # cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00500000 00010000 "qspi-boot"
mtd1: 002c0000 00010000 "qspi-linux"
mtd2: 00040000 00010000 "qspi-device-tree"
mtd3: 00400000 00010000 "qspi-rootfs"
mtd4: 00400000 00010000 "qspi-user"

 

The board is not zc702,but zedboard. The QSPI flash is not n25q128,but s25fl256s1.

The linux is 3.3.0 from Xilinx.

0 Kudos
norman_wong
Scholar
Scholar
14,633 Views
Registered: ‎05-28-2012

I took a quick look at the QPSI driver, spi-xilinx-qps.c, and the MTD driver, m25p80.c. Looks like the QSPI driver actually does operate in quad mode and has to interpret the SPI data stream sent to it from the MTD driver. As such the QSPI driver should recognize all the possible commands. Comparing the two drivers, I think the QSPI does not handle four commands. One of them is a Spansion command. Possible patch:

----drivers/mtd/devices/m25p80.c----
...
/* Used for SST flashes only. */
#define    OPCODE_AAI_WP           0xad    /* Auto address increment word program */
...
/* Used for Macronix flashes only. */
#define    OPCODE_EN4B             0xb7    /* Enter 4-byte mode */
#define    OPCODE_EX4B             0xe9    /* Exit 4-byte mode */
...
/* Used for Spansion flashes only. */
#define    OPCODE_BRWR             0x17    /* Bank register write */
...

----drivers/spi/spi-xilinx-qps.c----
...
/*
 * Definitions of the flash commands
 */
/* Flash opcodes in ascending order */
...
#define    XQSPIPS_FLASH_OPCODE_FAST_READ  0x0B    /* Fast read data bytes */
#define    XQSPIPS_FLASH_OPCODE_BRWR       0x17    /* Bank register write *//* Add */
#define    XQSPIPS_FLASH_OPCODE_BE_4K      0x20    /* Erase 4KiB block */
...
static struct xqspips_inst_format __devinitdata flash_inst[] = {
...
        { XQSPIPS_FLASH_OPCODE_QUAD_READ, 1, XQSPIPS_TXD_00_01_OFFSET },
        { XQSPIPS_FLASH_OPCODE_BRWR, 1, XQSPIPS_TXD_00_01_OFFSET }, /* Add */
        /* Add all the instructions supported by the flash device */
};

Note that the above is just a guess. I do not know what is the appropriate inst_size or offset value. To avoid damage to your flash, I'd suggest waiting for John Linn to confirm or dismiss my conclusions.

 

0 Kudos
gcwang
Observer
Observer
14,620 Views
Registered: ‎07-10-2012

Thanks very much!

http://www.xilinx.com/support/answers/50991.htm

My flash is s25fl256s1 which is Limited Flash Devices for Xilinx,These devices are not supported in the Xilinx Tools,so,the

flsahcp tool can not work well.

 

I modify the driver according to your suggest,but the flsahcp still can not to write the QSPI flash, as follows:

 

  /mnt # flashcp -v ramdisk8M.image.gz  /dev/mtd4
Erasing blocks: 51/51 (100%)
Writing data: 3257k/0k (100%))
Verifying data: 10k/0k (3257%)File does not seem to match flash data. First mismatch at 0x00000000-0x00002800

 

The u-boot-xarm can write and read  QSPI flash by sf command.

 

--/driver/spi/zynq_qspi.c-- (u-boot)----

/*
 * Definitions of the flash commands
 */
/* Flash opcodes in ascending order */
#define XQSPIPSS_FLASH_OPCODE_WRSR 0x01 /* Write status register */
#define XQSPIPSS_FLASH_OPCODE_PP 0x02 /* Page program */
#define XQSPIPSS_FLASH_OPCODE_NORM_READ 0x03 /* Normal read data bytes */
#define XQSPIPSS_FLASH_OPCODE_WRDS 0x04 /* Write disable */
#define XQSPIPSS_FLASH_OPCODE_RDSR1 0x05 /* Read status register 1 */
#define XQSPIPSS_FLASH_OPCODE_WREN 0x06 /* Write enable */
#define XQSPIPSS_FLASH_OPCODE_FAST_READ 0x0B /* Fast read data bytes */
#define XQSPIPSS_FLASH_OPCODE_BE_4K 0x20 /* Erase 4KiB block */
#define XQSPIPSS_FLASH_OPCODE_RDSR2 0x35 /* Read status register 2 */
#define XQSPIPSS_FLASH_OPCODE_DUAL_READ 0x3B /* Dual read data bytes */
#define XQSPIPSS_FLASH_OPCODE_BE_32K 0x52 /* Erase 32KiB block */
#define XQSPIPSS_FLASH_OPCODE_QUAD_READ 0x6B /* Quad read data bytes */
#define XQSPIPSS_FLASH_OPCODE_ERASE_SUS 0x75 /* Erase suspend */
#define XQSPIPSS_FLASH_OPCODE_ERASE_RES 0x7A /* Erase resume */
#define XQSPIPSS_FLASH_OPCODE_RDID 0x9F /* Read JEDEC ID */
#define XQSPIPSS_FLASH_OPCODE_BE 0xC7 /* Erase whole flash block */
#define XQSPIPSS_FLASH_OPCODE_SE 0xD8 /* Sector erase (usually 64KB)*/

 

/*
 * List of all the QSPI instructions and its format
 */
static struct xqspips_inst_format __devinitdata flash_inst[] = {
 { XQSPIPSS_FLASH_OPCODE_WREN, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_WRDS, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_RDSR1, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_RDSR2, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_WRSR, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_PP, 4, XQSPIPSS_TXD_00_00_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_SE, 4, XQSPIPSS_TXD_00_00_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_BE_32K, 4, XQSPIPSS_TXD_00_00_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_BE_4K, 4, XQSPIPSS_TXD_00_00_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_BE, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_ERASE_SUS, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_ERASE_RES, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_RDID, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_NORM_READ, 4, XQSPIPSS_TXD_00_00_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_FAST_READ, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_DUAL_READ, 1, XQSPIPSS_TXD_00_01_OFFSET },
 { XQSPIPSS_FLASH_OPCODE_QUAD_READ, 1, XQSPIPSS_TXD_00_01_OFFSET },
 /* Add all the instructions supported by the flash device */
};

 

From the zynq_qspi.c, which is not include the "OPCODE_BRWR 0x17“but still can work.

0 Kudos
norman_wong
Scholar
Scholar
14,612 Views
Registered: ‎05-28-2012

I believe the U-Boot "sf" code operates in serial mode. I haven't had a lot of success with the quad mode u-boot driver. I usually have to fall back to the serial mode.

 

The Linux MTD driver appears to use OPCODE_BRWR(0x17). The QSPI appears to operate in quad mode and is coded especially for attached quad SPI flash. Implies that there is no other quad SPI devices out there. Another thought would be to use a serial mode driver instead. No idea how to setup the device tree and kernel config to do that.

 

0 Kudos
gcwang
Observer
Observer
14,597 Views
Registered: ‎07-10-2012

I study the datasheet of S25FL128S_256_00.pdf and find the addr_width is error.

The driver of Xilinx perhaps can not support the 4byte addr,but 3byte addr. 3byte addr is just for up 16M flash and 4byte addr is for more than 16M flash,such as 32M. In 4byte addr mode, the driver of Xilinx can not work well.so,i modify the mtd driver and fixed the 3byte addr mode,after then, the driver of Xilinx can work well,but just for 16M flash of spansion.

 

-----------/driver/mtd/devices/m25p80.c----mp25_probe()-----

if (info->addr_width)
  flash->addr_width = info->addr_width;
 else {
  /* enable 4-byte addressing if the device exceeds 16MiB */
  if (flash->mtd.size > 0x1000000) {
   
   //set_4byte(flash, info->jedec_id, 1);

   //flash->addr_width = 4;   
   set_4byte(flash,info->jedec_id,0);   /*just for zedboard*/
   flash->addr_width = 3;     );/*gcwang add 0926*/
 }

I think if the driver support the 4byte addr mode of spansion,need to add 4byte addr command or set the BRWR(0x17) register(bit 0) in conjunction of 3byte addr mode. Hoping  the xilinx can provide the new driver of QSPI which can support the  spansion flash.

0 Kudos
norman_wong
Scholar
Scholar
6,579 Views
Registered: ‎05-28-2012

I think you found the problem. The QSPI driver assumes 3 byte addresses. This means that the QSPI driver cannot address more than 16MB of any QSPI flash. A work-around might be to change all the inst_size fields in the flash_inst array from 4 to 5 to handle the extra address byte. Other changes are probably required. However this line from AR#50991:

 

"Currently QPSI is only supported up to 16MB in single mode or 32 MB in dual mode due to limitations in the linear controller."

 

would imply that the limitation is in HW and the SW can do nothing about.

0 Kudos
milosoftware
Scholar
Scholar
6,435 Views
Registered: ‎10-26-2012

I've just spent several hours on the same issue before I discovered this thread. Indeed, limiting to 3 byte addressing works around the issue.

 

What I would really like to know from a Xilinx representative:

Is that 16MB limit permanent? In other words, is that a hardware limitation?

 

Or can this be fixed in the driver?

0 Kudos
baraq
Newbie
Newbie
6,397 Views
Registered: ‎12-26-2012

No answer yet for the HW/SW limitation issue?

0 Kudos