Bug-Fixes for FlexSPI

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Bug-Fixes for FlexSPI

2,934 Views
cfi
Contributor II

We are using a SoM with an i.MX8M-Mini and tried to use the FlexSPI to communicate with an FPGA which simulates a flash memory using 1-1-4 or 1-4-4 transfer mode.

To get that working we had to fix or extend the linux drivers at the following places:

1) ...\linux-imx\drivers\mtd\spi-nor\spi-nor.c

Support of the 1-4-4-DTR read-mode is read from the wrong bit of the SFDP table:

=> inside `static const struct sfdp_bfpt_read sfdp_bfpt_reads[]`

 

    /* Fast Read 1-4-4-DTR */

    {

        SNOR_HWCAPS_READ_1_4_4_DTR,

        BFPT_DWORD(1), BIT(21), /* Supported bit */

        BFPT_DWORD(3), 0,   /* Settings */

        SNOR_PROTO_1_4_4_DTR,

    },

 

to

 

    /* Fast Read 1-4-4-DTR */

    {

        SNOR_HWCAPS_READ_1_4_4_DTR,

        BFPT_DWORD(1), BIT(19), /* Supported bit */

        BFPT_DWORD(3), 0,   /* Settings */

        SNOR_PROTO_1_4_4_DTR,

    },

 

2) ...\linux-imx\drivers\mtd\spi-nor\fsl-flexspi.c

HW-Caps of the controller are missing support for 1-1-4 and 1-4-4:

=> inside `static int fsl_flexspi_probe(struct platform_device *pdev)`

 

    struct spi_nor_hwcaps hwcaps = {

        .mask = SNOR_HWCAPS_PP,

    };

 

to

 

    struct spi_nor_hwcaps hwcaps = {

        .mask = SNOR_HWCAPS_READ_1_1_4 |

            SNOR_HWCAPS_READ_1_4_4 |

            SNOR_HWCAPS_PP,

    };

3) ...\linux-imx\drivers\mtd\spi-nor\fsl-flexspi.c

LUT-initialization is not performed for 1-4-4:

=> inside `static void fsl_flexspi_init_lut(struct fsl_flexspi *flex)`

 

    /* DDR Quad I/O Read     */

    } else if (op == SPINOR_OP_READ_1_4_4_DTR || op == SPINOR_OP_READ_1_4_4_DTR_4B) {

        /* read mode : 1-4-4, such as Spansion s25fl128s. */

 

to

 

    /* DDR Quad I/O Read     */

    } else if (op == SPINOR_OP_READ_1_4_4 || op == SPINOR_OP_READ_1_4_4_4B

                           || op == SPINOR_OP_READ_1_4_4_DTR || op == SPINOR_OP_READ_1_4_4_DTR_4B) {

        /* read mode : 1-4-4, such as Spansion s25fl128s. */

4) ...\linux-imx\drivers\mtd\spi-nor\fsl-flexspi.c

Sequence Id for 1-4-4 missing

=> inside `static int fsl_flexspi_get_seqid(struct fsl_flexspi *flex, u8 cmd)`

 

    switch (cmd) {

    case SPINOR_OP_READ_1_1_4_DTR:

    case SPINOR_OP_READ_1_8_8_DTR_4B:

    case SPINOR_OP_READ_1_4_4_DTR:

    case SPINOR_OP_READ_1_4_4_DTR_4B:

    case SPINOR_OP_READ_1_1_4_4B:

    case SPINOR_OP_READ_1_1_4:

    case SPINOR_OP_READ_4B:

    case SPINOR_OP_READ:

        return SEQID_QUAD_READ;

 

to

 

    switch (cmd) {

    case SPINOR_OP_READ_1_1_4_DTR:

    case SPINOR_OP_READ_1_8_8_DTR_4B:

    case SPINOR_OP_READ_1_4_4_DTR:

    case SPINOR_OP_READ_1_4_4_DTR_4B:

    case SPINOR_OP_READ_1_1_4_4B:

    case SPINOR_OP_READ_1_1_4:

    case SPINOR_OP_READ_1_4_4_4B:

    case SPINOR_OP_READ_1_4_4:

    case SPINOR_OP_READ_4B:

    case SPINOR_OP_READ:

        return SEQID_QUAD_READ;

Labels (1)
5 Replies

2,527 Views
draven
Contributor III

Thanks for your reply cfi,

So I changed what you changed, really works for me with real nor flash.

&flexspi0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexspi0>;
status = "okay";

flash0: mx66u51235f@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "macronix,mx66u51235f";
spi-max-frequency = <84000000>;
status = "okay";
spi-nor,ddr-quad-read-dummy = <6>;
};
}; 

And now flexspi start correctly.

root@imx8qxpmek:~# dmesg | grep flex
[ 2.232151] fsl-flexspi 5d120000.flexspi: mx66u51235f (65536 Kbytes)

Also read sequence with mtd_debug tool, but I dont know it is true or not.

root@imx8qxpmek:~# mtd_debug read /dev/mtd0 0 5 read_test.txt
Copied 5 bytes from address 0x00000000 in flash to read_test.txt
root@imx8qxpmek:~# cat read_test.txt
����aroot@imx8qxpmek:~#

Because I think there is a problem. I want to help from you here.

root@imx8qxpmek:~# mtd_debug write /dev/mtd0 0 5 write_test.txt
[ 1069.324509] fsl-flexspi 5d120000.flexspi: Unsupported cmd 0x12
Copied 5 bytes from write_test.txt to address 0x00000000 in flash

That I must do for write?

0 Kudos
Reply

2,527 Views
cfi
Contributor II

Hi,

I'm sorry, but I can't really help you with writing, as we only do read from our (simulated) flash. But the error suggest that the flash is not supporting the used command to write. Can you use a Scope or better logic analyzer to get the SFDP table from the flash? (this is requested/sent after the initial 0x9F command)

0 Kudos
Reply

2,527 Views
draven
Contributor III

cfi‌ How did you change your "spi_nor_scan" function in drivers/mtd/spi-nor/spi-nor.c. 

Because if I not change like this in "spi_nor_read_id" function I get error.

for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
info = &spi_nor_ids[tmp];
if(info->name == "mt35xu512aba")
{
return &spi_nor_ids[tmp];
}
/*
if (info->id_len) {
if (!memcmp(info->id, id, info->id_len))
return &spi_nor_ids[tmp];
}*/
}

But no error with above change.

Have you changed anything different from your commits?

Also How is your device-tree configration?

My problem same like you. Now I try write with : 

root@imx8qxpmek:~# mtd_debug write /dev/mtd0 1 1 test
Copied 1 bytes from test to address 0x00000001 in flash

I look QSPI pins with scope but pins not change. 

root@imx8qxpmek:~# dmesg | grep flex
[ 2.232143] fsl-flexspi 5d120000.flexspi: mt35xu512aba (65536 Kbytes)

My device-tree section : 

pinctrl_flexspi0: flexspi0grp {
fsl,pins = <
SC_P_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x00000040
SC_P_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x00000040
SC_P_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x00000040
SC_P_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x00000040
SC_P_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x00000040
SC_P_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x00000040
SC_P_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x00000020
SC_P_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x00000020
>;
};
};
};

&flexspi0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flexspi0>;
status = "okay";
fpgacom: fpgacom0@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
compatible = "micron,mt35xu512aba";
spi-max-frequency = <133000000>;
spi-nor,ddr-quad-read-dummy = <8>;
status = "okay";
};
};

 Also not connected any hardware to QSPI pins. They are free at this situation.

0 Kudos
Reply

2,527 Views
cfi
Contributor II

Hi yildizberat@gmail.com

all changes we did are in my post - nothing else needed. Our device tree looks like the following:

        pinctrl_flexspi0: flexspi0grp {
            fsl,pins = <
                MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK        0x1c2
                MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B        0x82
                MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0        0x82
                MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1        0x82
                MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2        0x82
                MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3        0x82
            >;
        };

and

      &flexspi {

      pinctrl-names = "default";

      pinctrl-0 = <&pinctrl_flexspi0>;

      status = "okay";

 

      flash0: mt25qu256aba@0 {

      reg = <0>;

      #address-cells = <1>;

      #size-cells = <1>;

      compatible = "winbond,w25q128fw", "jedec,spi-nor";

      spi-max-frequency = <32000000>;

      spi-nor,ddr-quad-read-dummy = <0>;                        

      };

      };

But some notes from my side:

  • You need to connect a flash to the QSPI-Pins or the MTD-device is not recognizes as there is some initial communication between the SoM and the flash (e.g. "READ JEDEC ID" - 0x9F)
  • As far as I could see the "mt35xu512aba" is a x1/x8 flash, but you try to use it as x4 - does the flash really support this?
0 Kudos
Reply

2,528 Views
jimmychan
NXP TechSupport
NXP TechSupport

Thanks for the sharing.

0 Kudos
Reply