18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2005, Intec Automation Inc. 48c2ecf20Sopenharmony_ci * Copyright (C) 2014, Freescale Semiconductor, Inc. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/mtd/spi-nor.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "core.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic int 128c2ecf20Sopenharmony_cis25fs_s_post_bfpt_fixups(struct spi_nor *nor, 138c2ecf20Sopenharmony_ci const struct sfdp_parameter_header *bfpt_header, 148c2ecf20Sopenharmony_ci const struct sfdp_bfpt *bfpt, 158c2ecf20Sopenharmony_ci struct spi_nor_flash_parameter *params) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci /* 188c2ecf20Sopenharmony_ci * The S25FS-S chip family reports 512-byte pages in BFPT but 198c2ecf20Sopenharmony_ci * in reality the write buffer still wraps at the safe default 208c2ecf20Sopenharmony_ci * of 256 bytes. Overwrite the page size advertised by BFPT 218c2ecf20Sopenharmony_ci * to get the writes working. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci params->page_size = 256; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci return 0; 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic struct spi_nor_fixups s25fs_s_fixups = { 298c2ecf20Sopenharmony_ci .post_bfpt = s25fs_s_post_bfpt_fixups, 308c2ecf20Sopenharmony_ci}; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic const struct flash_info spansion_parts[] = { 338c2ecf20Sopenharmony_ci /* Spansion/Cypress -- single (large) sector size only, at least 348c2ecf20Sopenharmony_ci * for the chips listed here (without boot sectors). 358c2ecf20Sopenharmony_ci */ 368c2ecf20Sopenharmony_ci { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 378c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 388c2ecf20Sopenharmony_ci { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 398c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 408c2ecf20Sopenharmony_ci { "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64, 418c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 428c2ecf20Sopenharmony_ci USE_CLSR) }, 438c2ecf20Sopenharmony_ci { "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, 448c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 458c2ecf20Sopenharmony_ci USE_CLSR) }, 468c2ecf20Sopenharmony_ci { "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128, 478c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 488c2ecf20Sopenharmony_ci USE_CLSR) }, 498c2ecf20Sopenharmony_ci { "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512, 508c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 518c2ecf20Sopenharmony_ci USE_CLSR) }, 528c2ecf20Sopenharmony_ci { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256, 538c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 548c2ecf20Sopenharmony_ci SPI_NOR_HAS_LOCK | USE_CLSR) }, 558c2ecf20Sopenharmony_ci { "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256, 568c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) 578c2ecf20Sopenharmony_ci .fixups = &s25fs_s_fixups, }, 588c2ecf20Sopenharmony_ci { "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128, 598c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 608c2ecf20Sopenharmony_ci USE_CLSR) }, 618c2ecf20Sopenharmony_ci { "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 628c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 638c2ecf20Sopenharmony_ci USE_CLSR) }, 648c2ecf20Sopenharmony_ci { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, 658c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) 668c2ecf20Sopenharmony_ci .fixups = &s25fs_s_fixups, }, 678c2ecf20Sopenharmony_ci { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, 688c2ecf20Sopenharmony_ci { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, 698c2ecf20Sopenharmony_ci { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 708c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 718c2ecf20Sopenharmony_ci USE_CLSR) }, 728c2ecf20Sopenharmony_ci { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, 738c2ecf20Sopenharmony_ci SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 748c2ecf20Sopenharmony_ci USE_CLSR) }, 758c2ecf20Sopenharmony_ci { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, 768c2ecf20Sopenharmony_ci { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, 778c2ecf20Sopenharmony_ci { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, 788c2ecf20Sopenharmony_ci { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, 798c2ecf20Sopenharmony_ci { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, 808c2ecf20Sopenharmony_ci { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, 818c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 828c2ecf20Sopenharmony_ci { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, 838c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 848c2ecf20Sopenharmony_ci { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, 858c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 868c2ecf20Sopenharmony_ci { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, 878c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 888c2ecf20Sopenharmony_ci { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, 898c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, 908c2ecf20Sopenharmony_ci { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, 918c2ecf20Sopenharmony_ci { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, 928c2ecf20Sopenharmony_ci { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, 938c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ) }, 948c2ecf20Sopenharmony_ci { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16, 958c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ) }, 968c2ecf20Sopenharmony_ci { "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128, 978c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 988c2ecf20Sopenharmony_ci SPI_NOR_4B_OPCODES) }, 998c2ecf20Sopenharmony_ci { "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256, 1008c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 1018c2ecf20Sopenharmony_ci SPI_NOR_4B_OPCODES) }, 1028c2ecf20Sopenharmony_ci { "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512, 1038c2ecf20Sopenharmony_ci SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | 1048c2ecf20Sopenharmony_ci SPI_NOR_4B_OPCODES) }, 1058c2ecf20Sopenharmony_ci { "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1, 1068c2ecf20Sopenharmony_ci SPI_NOR_NO_ERASE) }, 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic void spansion_post_sfdp_fixups(struct spi_nor *nor) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci if (nor->params->size <= SZ_16M) 1128c2ecf20Sopenharmony_ci return; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci nor->flags |= SNOR_F_4B_OPCODES; 1158c2ecf20Sopenharmony_ci /* No small sector erase for 4-byte command set */ 1168c2ecf20Sopenharmony_ci nor->erase_opcode = SPINOR_OP_SE; 1178c2ecf20Sopenharmony_ci nor->mtd.erasesize = nor->info->sector_size; 1188c2ecf20Sopenharmony_ci} 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic const struct spi_nor_fixups spansion_fixups = { 1218c2ecf20Sopenharmony_ci .post_sfdp = spansion_post_sfdp_fixups, 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ciconst struct spi_nor_manufacturer spi_nor_spansion = { 1258c2ecf20Sopenharmony_ci .name = "spansion", 1268c2ecf20Sopenharmony_ci .parts = spansion_parts, 1278c2ecf20Sopenharmony_ci .nparts = ARRAY_SIZE(spansion_parts), 1288c2ecf20Sopenharmony_ci .fixups = &spansion_fixups, 1298c2ecf20Sopenharmony_ci}; 130