spi: fsl_qspi: Fix issues on arm64
Subsystems (3)
PATCH 1/4 spi: fsl_qspi: Fix issues on arm64
From: Yuan Yao <[email protected]>
The address value and size value get from dts "reg" property have type of u64 on arm64.
If we assign those values to "u32" variables, driver can't work correctly. Converting the type of those variables to fdt_xxx_t.
--- drivers/spi/fsl_qspi.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-)
drivers/spi/fsl_qspi.c +27 -19
@@ -92,9 +92,9 @@ DECLARE_GLOBAL_DATA_PTR;struct fsl_qspi_platdata {u32 flags;u32 speed_hz; -u32 reg_base; -u32 amba_base; -u32 amba_total_size; +fdt_addr_t reg_base; +fdt_addr_t amba_base; +fdt_size_t amba_total_size;u32 flash_num;u32 num_chipselect; };
@@ -940,8 +940,13 @@ static int fsl_qspi_probe(struct udevice *bus) priv->flags = plat->flags; priv->speed_hz = plat->speed_hz; - priv->amba_base[0 ] = plat->amba_base; - priv->amba_total_size = plat->amba_total_size; +/* +* QSPI SFADR width is 32bits, the max dest addr is 4GB-1. +* AMBA memory zone should be located on the 0~4GB space +* even on a 64bits cpu. +*/ + priv->amba_base[0 ] = (u32 )plat->amba_base; + priv->amba_total_size = (u32 )plat->amba_total_size; priv->flash_num = plat->flash_num; priv->num_chipselect = plat->num_chipselect;
@@ -984,10 +989,7 @@ static int fsl_qspi_probe(struct udevice *bus)static int fsl_qspi_ofdata_to_platdata (struct udevice *bus) { -struct reg_data { -u32 addr; -u32 size; - } regs_data[2 ]; +struct fdt_resource res_regs, res_mem;struct fsl_qspi_platdata *plat = bus->platdata;const void *blob = gd->fdt_blob;int node = bus->of_offset;
@@ -996,10 +998,16 @@ static int fsl_qspi_ofdata_to_platdata(struct udevice *bus)if (fdtdec_get_bool (blob, node,"big-endian" )) plat->flags |=QSPI_FLAG_REGMAP_ENDIAN_BIG ; - ret =fdtdec_get_int_array (blob, node,"reg" , (u32 *)regs_data, -sizeof (regs_data)/sizeof (u32)); + ret =fdt_get_named_resource (blob, node,"reg" ,"reg-names" , +"QuadSPI" , &res_regs); +if (ret) { +debug ("Error: can't get regs base addresses(ret = %d)!\n" , ret); +return -ENOMEM ; + } + ret =fdt_get_named_resource (blob, node,"reg" ,"reg-names" , +"QuadSPI-memory" , &res_mem);if (ret) { -debug ("Error: can't get base addresses (ret = %d)!\n" , ret); +debug ("Error: can't get AMBA base addresses(ret = %d)!\n" , ret);return -ENOMEM ; }
@@ -1017,16 +1025,16 @@ static int fsl_qspi_ofdata_to_platdata(struct udevice *bus) plat->num_chipselect =fdtdec_get_int (blob, node,"num-cs" ,FSL_QSPI_MAX_CHIPSELECT_NUM ); - plat->reg_base = regs_data[0 ].addr; - plat->amba_base = regs_data[1 ].addr; - plat->amba_total_size = regs_data[1 ].size; + plat->reg_base = res_regs.start; + plat->amba_base = res_mem.start; + plat->amba_total_size = res_mem.end - res_mem.start +1 ; plat->flash_num = flash_num; -debug ("%s: regs=<0x%x> <0x%x, 0x%x>, max-frequency=%d, endianess=%s\n" , +debug ("%s: regs=<0x%llx> <0x%llx, 0x%llx>, max-frequency=%d, endianess=%s\n" , __func__, - plat->reg_base, - plat->amba_base, - plat->amba_total_size, + (u64 )plat->reg_base, + (u64 )plat->amba_base, + (u64 )plat->amba_total_size, plat->speed_hz, plat->flags &QSPI_FLAG_REGMAP_ENDIAN_BIG ?"be" :"le" );
Signature · 1 line
2.1.0.27.g96db324
PATCH 2/5 spi: fsl_qspi: Assign AMBA mem according CS num in dts
From: Yuan Yao <[email protected]>
QSPI controller automatic enable the chipselect signal according the dest AMBA memory address. Now we distribute the AMBA memory zone averagely to every chipselect slave device according chipselect numbers got from dts node.
--- drivers/spi/fsl_qspi.c | 55 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-)
drivers/spi/fsl_qspi.c +43 -12
@@ -927,10 +927,11 @@ static int fsl_qspi_child_pre_probe(struct udevice *dev)static int fsl_qspi_probe (struct udevice *bus) { -u32 total_size; +u32 amba_size_per_chip;struct fsl_qspi_platdata *plat =dev_get_platdata (bus);struct fsl_qspi_priv *priv =dev_get_priv (bus);struct dm_spi_bus *dm_spi_bus; +int i; dm_spi_bus = bus->uclass_priv;
@@ -956,7 +957,22 @@ static int fsl_qspi_probe(struct udevice *bus)qspi_cfg_smpr (priv, ~(QSPI_SMPR_FSDLY_MASK |QSPI_SMPR_DDRSMP_MASK |QSPI_SMPR_FSPHS_MASK |QSPI_SMPR_HSENA_MASK ),0 ); - total_size =FSL_QSPI_FLASH_SIZE *FSL_QSPI_FLASH_NUM ; +/* +* Assign AMBA memory zone for every chipselect +* QuadSPI has two channels, every channel has two chipselects. +* If the property 'num-cs' in dts is 2, the AMBA memory will be divided +* into two parts and assign to every channel. This indicate that every +* channel only has one valid chipselect. +* If the property 'num-cs' in dts is 4, the AMBA memory will be divided +* into four parts and assign to every chipselect. +* Every channel will has two valid chipselects. +*/ + amba_size_per_chip = priv->amba_total_size >> + (priv->num_chipselect >>1 ); +for (i =1 ; i < priv->num_chipselect ; i++) + priv->amba_base[i] = + amba_size_per_chip + priv->amba_base[i -1 ]; +/* * Any read access to non-implemented addresses will provide * undefined results.
@@ -967,14 +983,30 @@ static int fsl_qspi_probe(struct udevice *bus)* setting the size of these devices to 0. This would ensure * that the complete memory map is assigned to only one flash device. */ -qspi_write32 (priv->flags, &priv->regs->sfa1ad, -FSL_QSPI_FLASH_SIZE | priv->amba_base[0 ]); -qspi_write32 (priv->flags, &priv->regs->sfa2ad, -FSL_QSPI_FLASH_SIZE | priv->amba_base[0 ]); -qspi_write32 (priv->flags, &priv->regs->sfb1ad, - total_size | priv->amba_base[0 ]); -qspi_write32 (priv->flags, &priv->regs->sfb2ad, - total_size | priv->amba_base[0 ]); +qspi_write32 (priv->flags, &priv->regs->sfa1ad, priv->amba_base[1 ]); +switch (priv->num_chipselect) { +case 2 : +qspi_write32 (priv->flags, &priv->regs->sfa2ad, + priv->amba_base[1 ]); +qspi_write32 (priv->flags, &priv->regs->sfb1ad, + priv->amba_base[1 ] + amba_size_per_chip); +qspi_write32 (priv->flags, &priv->regs->sfb2ad, + priv->amba_base[1 ] + amba_size_per_chip); +break ; +case 4 : +qspi_write32 (priv->flags, &priv->regs->sfa2ad, + priv->amba_base[2 ]); +qspi_write32 (priv->flags, &priv->regs->sfb1ad, + priv->amba_base[3 ]); +qspi_write32 (priv->flags, &priv->regs->sfb2ad, + priv->amba_base[3 ] + amba_size_per_chip); +break ; +default : +debug ("Error: Unsupported chipselect number %u!\n" , + priv->num_chipselect); +qspi_module_disable (priv,1 ); +return -EINVAL ; + }qspi_set_lut (priv);
@@ -1063,8 +1095,7 @@ static int fsl_qspi_claim_bus(struct udevice *dev) bus = dev->parent; priv =dev_get_priv (bus); - priv->cur_amba_base = - priv->amba_base[0 ] +FSL_QSPI_FLASH_SIZE * slave_plat->cs; + priv->cur_amba_base = priv->amba_base[slave_plat->cs];qspi_module_disable (priv,0 );
Signature · 1 line
2.1.0.27.g96db324
PATCH 2/5 spi: fsl_qspi: Assign AMBA mem according CS num in dts
Quoted 7 lines · Yuan Yao
From: Yuan Yao <[email protected]>
QSPI controller automatic enable the chipselect signal according the dest AMBA memory address. Now we distribute the AMBA memory zone averagely to every chipselect slave device according chipselect numbers got from dts node.
Quoted 7 lines
Signed-off-by Yuan Yao <[email protected]>Signed-off-by Prabhakar Kushwaha <[email protected]>Signed-off-by Yuan Yao <[email protected]>--- drivers/spi/fsl_qspi.c | 55 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 12 deletions(-)
Jagan,
I plan to merge this set. Please let me know if you have any comment.
York
PATCH 3/5 spi: fsl_qspi: Enable Spansion S25FS-S family flashes
In reply to Yuan YaoFrom: Yuan Yao <[email protected]>
The flash type of LS2085AQDS QSPI is S25FS256S.
It has special write any device register command and read any device register command.
This patch enable support for those commands.
--- drivers/mtd/spi/sf_internal.h | 5 ++++ drivers/spi/fsl_qspi.c | 58 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 6 deletions(-)
drivers/mtd/spi/sf_internal.h +5 -0
@@ -127,6 +127,11 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, const void *buf);#endif +#ifdef CONFIG_SPI_FLASH_SPANSION +/* Used for Spansion S25FS-S family flash only. */ +#define CMD_SPANSION_RDAR 0x65/* Read any device register */ +#define CMD_SPANSION_WRAR 0x71/* Write any device register */ +#endif /** * struct spi_flash_params - SPI/QSPI flash device params structure *
drivers/spi/fsl_qspi.c +52 -6
129 lines not on this page · raw message
Signature · 1 line
2.1.0.27.g96db324
PATCH 4/5 sf: Disable 4-KB erase command for SPANSION S25FS-S family
In reply to Yuan YaoFrom: Yuan Yao <[email protected]>
The S25FS-S family physical sectors may be configured as a hybrid combination of eight 4-kB parameter sectors at the top or bottom of the address space with all but one of the remaining sectors being uniform size.
The default status of the flash is in this hybrid architecture. The parameter sectors and the uniform sectors have different erase commands.
This patch disable the hybrid sector architecture then the flash will has uniform sector size and uniform erase command.
This configuration is temporary, the flash will revert to hybrid architecture after power on reset.
--- drivers/mtd/spi/spi_flash.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+)
drivers/mtd/spi/spi_flash.c +72 -0
@@ -970,6 +970,43 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) }#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ +#ifdef CONFIG_SPI_FLASH_SPANSION +static int spansion_s25fss_disable_4KB_erase (struct spi_slave *spi) +{ +u8 cmd[4 ]; +u32 offset =0x800004 ;/* CR3V register offset */ +u8 cr3v; +int ret; + + cmd[0 ] =CMD_SPANSION_RDAR ; + cmd[1 ] = offset >>16 ; + cmd[2 ] = offset >>8 ; + cmd[3 ] = offset >>0 ; + + ret =spi_flash_cmd_read (spi, cmd,4 , &cr3v,1 ); +if (ret) +return -EIO ; +/* CR3V bit3: 4-KB Erase */ +if (cr3v &0x8 ) +return 0 ; + + cmd[0 ] =CMD_SPANSION_WRAR ; + cr3v |=0x8 ; + ret =spi_flash_cmd_write (spi, cmd,4 , &cr3v,1 ); +if (ret) +return -EIO ; + + cmd[0 ] =CMD_SPANSION_RDAR ; + ret =spi_flash_cmd_read (spi, cmd,4 , &cr3v,1 ); +if (ret) +return -EIO ; +if (!(cr3v &0x8 )) +return -EFAULT ; + +return 0 ; +} +#endif +int spi_flash_scan (struct spi_flash *flash) {struct spi_slave *spi = flash->spi;
@@ -1020,6 +1057,41 @@ int spi_flash_scan(struct spi_flash *flash)return -EPROTONOSUPPORT ; } +#ifdef CONFIG_SPI_FLASH_SPANSION +/* +* The S25FS-S family physical sectors may be configured as a +* hybrid combination of eight 4-kB parameter sectors +* at the top or bottom of the address space with all +* but one of the remaining sectors being uniform size. +* The Parameter Sector Erase commands (20h or 21h) must +* be used to erase the 4-kB parameter sectors individually. +* The Sector (uniform sector) Erase commands (D8h or DCh) +* must be used to erase any of the remaining +* sectors, including the portion of highest or lowest address +* sector that is not overlaid by the parameter sectors. +* The uniform sector erase command has no effect on parameter sectors. +*/ +if (jedec ==0x0219 && (ext_jedec &0xff00 ) ==0x4d00 ) { +int ret; +u8 id[6 ]; + +/* Read the ID codes again, 6 bytes */ + ret =spi_flash_cmd (flash->spi,CMD_READ_ID , id,sizeof (id)); +if (ret) +return -EIO ; + + ret =memcmp (id, idcode,5 ); +if (ret) +return -EIO ; + +/* 0x81: S25FS-S family 0x80: S25FL-S family */ +if (id[5 ] ==0x81 ) { + ret =spansion_s25fss_disable_4KB_erase (spi); +if (ret) +return ret; + } + } +#endif /* Flash powers up read-only, so clear BP# bits */ if (idcode[0] == SPI_FLASH_CFI_MFR_ATMEL || idcode[0] == SPI_FLASH_CFI_MFR_MACRONIX ||
Signature · 1 line
2.1.0.27.g96db324
PATCH 5/5 armv8/ls1043a: update the node for QSPI support
In reply to Yuan YaoFrom: Yuan Yao <[email protected]>
The address value and size value set for QSPI dts node "reg" property have type of u64 on arm64.
--- arch/arm/dts/fsl-ls1043a.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm/dts/fsl-ls1043a.dtsi +3 -2
@@ -240,8 +240,9 @@ compatible = "fsl,vf610-qspi"; #address-cells = <1>; #size-cells = <0>; - reg = <0x1550000 0x10000>, - <0x40000000 0x4000000>; + reg = <0x0 0x1550000 0x0 0x10000>, + <0x0 0x40000000 0x0 0x4000000>; + reg-names = "QuadSPI", "QuadSPI-memory"; num-cs = <2>; big-endian; status = "disabled";
Signature · 1 line
2.1.0.27.g96db324
PATCH 1/4 spi: fsl_qspi: Fix issues on arm64
In reply to Yuan YaoQuoted 11 lines · Yuan Yao
From: Yuan Yao <[email protected]>
The address value and size value get from dts "reg" property have type of u64 on arm64.
If we assign those values to "u32" variables, driver can't work correctly. Converting the type of those variables tofdt_xxx_t.Signed-off-by Yuan Yao <[email protected]>Signed-off-by Prabhakar Kushwaha <[email protected]>Signed-off-by Yuan Yao <[email protected]>---
Yuan,
Did you mean to put both your legacy freescale email id and your nxp email id in the signature lines? I can remove your freescale id if it was added by mistake. I need to reformat your commit message anyway because some lines are too long.
York
PATCH 1/4 spi: fsl_qspi: Fix issues on arm64
Quoted 13 lines · York Sun
Quoted 11 lines · Yuan Yao
From: Yuan Yao <[email protected]>
The address value and size value get from dts "reg" property have type of u64 on arm64.
If we assign those values to "u32" variables, driver can't work correctly. Converting the type of those variables tofdt_xxx_t.Signed-off-by Yuan Yao <[email protected]>Signed-off-by Prabhakar Kushwaha <[email protected]>Signed-off-by Yuan Yao <[email protected]>---
Quoted 8 lines
Yuan,
Did you mean to put both your legacy freescale email id and your nxp email id in the signature lines? I can remove your freescale id if it was added by mistake. I need to reformat your commit message anyway because some lines are too long.
York
Yes, you can remove the Freescale id.
Thanks for your review and helps.