2020-03-13 22:42:50 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright ( C ) 2005 , Intec Automation Inc .
* Copyright ( C ) 2014 , Freescale Semiconductor , Inc .
*/
# include <linux/mtd/spi-nor.h>
# include "core.h"
static const struct flash_info xilinx_parts [ ] = {
/* Xilinx S3AN Internal Flash */
{ " 3S50AN " , S3AN_INFO ( 0x1f2200 , 64 , 264 ) } ,
{ " 3S200AN " , S3AN_INFO ( 0x1f2400 , 256 , 264 ) } ,
{ " 3S400AN " , S3AN_INFO ( 0x1f2400 , 256 , 264 ) } ,
{ " 3S700AN " , S3AN_INFO ( 0x1f2500 , 512 , 264 ) } ,
{ " 3S1400AN " , S3AN_INFO ( 0x1f2600 , 512 , 528 ) } ,
} ;
/*
* This code converts an address to the Default Address Mode , that has non
* power of two page sizes . We must support this mode because it is the default
* mode supported by Xilinx tools , it can access the whole flash area and
* changing over to the Power - of - two mode is irreversible and corrupts the
* original data .
* Addr can safely be unsigned int , the biggest S3AN device is smaller than
* 4 MiB .
*/
static u32 s3an_convert_addr ( struct spi_nor * nor , u32 addr )
{
2021-10-29 20:26:12 +03:00
u32 page_size = nor - > params - > page_size ;
2020-03-13 22:42:50 +03:00
u32 offset , page ;
2021-10-29 20:26:12 +03:00
offset = addr % page_size ;
page = addr / page_size ;
page < < = ( page_size > 512 ) ? 10 : 9 ;
2020-03-13 22:42:50 +03:00
return page | offset ;
}
static int xilinx_nor_setup ( struct spi_nor * nor ,
const struct spi_nor_hwcaps * hwcaps )
{
2021-10-29 20:26:12 +03:00
u32 page_size ;
2020-03-13 22:42:50 +03:00
int ret ;
ret = spi_nor_xread_sr ( nor , nor - > bouncebuf ) ;
if ( ret )
return ret ;
nor - > erase_opcode = SPINOR_OP_XSE ;
nor - > program_opcode = SPINOR_OP_XPP ;
nor - > read_opcode = SPINOR_OP_READ ;
nor - > flags | = SNOR_F_NO_OP_CHIP_ERASE ;
/*
* This flashes have a page size of 264 or 528 bytes ( known as
* Default addressing mode ) . It can be changed to a more standard
* Power of two mode where the page size is 256 / 512. This comes
* with a price : there is 3 % less of space , the data is corrupted
* and the page size cannot be changed back to default addressing
* mode .
*
* The current addressing mode can be read from the XRDSR register
* and should not be changed , because is a destructive operation .
*/
if ( nor - > bouncebuf [ 0 ] & XSR_PAGESIZE ) {
/* Flash in Power of 2 mode */
2021-10-29 20:26:12 +03:00
page_size = ( nor - > params - > page_size = = 264 ) ? 256 : 512 ;
nor - > params - > page_size = page_size ;
nor - > mtd . writebufsize = page_size ;
2021-12-07 17:02:41 +03:00
nor - > params - > size = 8 * page_size * nor - > info - > n_sectors ;
2021-10-29 20:26:12 +03:00
nor - > mtd . erasesize = 8 * page_size ;
2020-03-13 22:42:50 +03:00
} else {
/* Flash in Default addressing mode */
2020-03-13 22:42:53 +03:00
nor - > params - > convert_addr = s3an_convert_addr ;
2020-03-13 22:42:50 +03:00
nor - > mtd . erasesize = nor - > info - > sector_size ;
}
return 0 ;
}
2021-10-29 20:26:17 +03:00
static void xilinx_late_init ( struct spi_nor * nor )
2020-03-13 22:42:50 +03:00
{
2020-03-13 22:42:53 +03:00
nor - > params - > setup = xilinx_nor_setup ;
2020-03-13 22:42:50 +03:00
}
static const struct spi_nor_fixups xilinx_fixups = {
2021-10-29 20:26:17 +03:00
. late_init = xilinx_late_init ,
2020-03-13 22:42:50 +03:00
} ;
const struct spi_nor_manufacturer spi_nor_xilinx = {
. name = " xilinx " ,
. parts = xilinx_parts ,
. nparts = ARRAY_SIZE ( xilinx_parts ) ,
. fixups = & xilinx_fixups ,
} ;