162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2005, Intec Automation Inc. 462306a36Sopenharmony_ci * Copyright (C) 2014, Freescale Semiconductor, Inc. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/mtd/spi-nor.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "core.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistatic int 1262306a36Sopenharmony_cimx25l25635_post_bfpt_fixups(struct spi_nor *nor, 1362306a36Sopenharmony_ci const struct sfdp_parameter_header *bfpt_header, 1462306a36Sopenharmony_ci const struct sfdp_bfpt *bfpt) 1562306a36Sopenharmony_ci{ 1662306a36Sopenharmony_ci /* 1762306a36Sopenharmony_ci * MX25L25635F supports 4B opcodes but MX25L25635E does not. 1862306a36Sopenharmony_ci * Unfortunately, Macronix has re-used the same JEDEC ID for both 1962306a36Sopenharmony_ci * variants which prevents us from defining a new entry in the parts 2062306a36Sopenharmony_ci * table. 2162306a36Sopenharmony_ci * We need a way to differentiate MX25L25635E and MX25L25635F, and it 2262306a36Sopenharmony_ci * seems that the F version advertises support for Fast Read 4-4-4 in 2362306a36Sopenharmony_ci * its BFPT table. 2462306a36Sopenharmony_ci */ 2562306a36Sopenharmony_ci if (bfpt->dwords[SFDP_DWORD(5)] & BFPT_DWORD5_FAST_READ_4_4_4) 2662306a36Sopenharmony_ci nor->flags |= SNOR_F_4B_OPCODES; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci return 0; 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic const struct spi_nor_fixups mx25l25635_fixups = { 3262306a36Sopenharmony_ci .post_bfpt = mx25l25635_post_bfpt_fixups, 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic const struct flash_info macronix_nor_parts[] = { 3662306a36Sopenharmony_ci /* Macronix */ 3762306a36Sopenharmony_ci { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1) 3862306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 3962306a36Sopenharmony_ci { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4) 4062306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 4162306a36Sopenharmony_ci { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8) 4262306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 4362306a36Sopenharmony_ci { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16) }, 4462306a36Sopenharmony_ci { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32) 4562306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 4662306a36Sopenharmony_ci { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64) 4762306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 4862306a36Sopenharmony_ci { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64) 4962306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 5062306a36Sopenharmony_ci { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128) 5162306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 5262306a36Sopenharmony_ci { "mx25u2033e", INFO(0xc22532, 0, 64 * 1024, 4) 5362306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 5462306a36Sopenharmony_ci { "mx25u3235f", INFO(0xc22536, 0, 64 * 1024, 64) 5562306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 5662306a36Sopenharmony_ci SPI_NOR_QUAD_READ) }, 5762306a36Sopenharmony_ci { "mx25u4035", INFO(0xc22533, 0, 64 * 1024, 8) 5862306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 5962306a36Sopenharmony_ci { "mx25u8035", INFO(0xc22534, 0, 64 * 1024, 16) 6062306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 6162306a36Sopenharmony_ci { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128) 6262306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 6362306a36Sopenharmony_ci { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256) 6462306a36Sopenharmony_ci FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) 6562306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) }, 6662306a36Sopenharmony_ci { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256) }, 6762306a36Sopenharmony_ci { "mx25r1635f", INFO(0xc22815, 0, 64 * 1024, 32) 6862306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 6962306a36Sopenharmony_ci SPI_NOR_QUAD_READ) }, 7062306a36Sopenharmony_ci { "mx25r3235f", INFO(0xc22816, 0, 64 * 1024, 64) 7162306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 7262306a36Sopenharmony_ci SPI_NOR_QUAD_READ) }, 7362306a36Sopenharmony_ci { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256) 7462306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 7562306a36Sopenharmony_ci SPI_NOR_QUAD_READ) }, 7662306a36Sopenharmony_ci { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512) 7762306a36Sopenharmony_ci NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 7862306a36Sopenharmony_ci .fixups = &mx25l25635_fixups }, 7962306a36Sopenharmony_ci { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512) 8062306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K) 8162306a36Sopenharmony_ci FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 8262306a36Sopenharmony_ci { "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024) 8362306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 8462306a36Sopenharmony_ci FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 8562306a36Sopenharmony_ci { "mx25uw51245g", INFOB(0xc2813a, 0, 0, 0, 4) 8662306a36Sopenharmony_ci PARSE_SFDP 8762306a36Sopenharmony_ci FLAGS(SPI_NOR_RWW) }, 8862306a36Sopenharmony_ci { "mx25v8035f", INFO(0xc22314, 0, 64 * 1024, 16) 8962306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 9062306a36Sopenharmony_ci SPI_NOR_QUAD_READ) }, 9162306a36Sopenharmony_ci { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512) }, 9262306a36Sopenharmony_ci { "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024) 9362306a36Sopenharmony_ci NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 9462306a36Sopenharmony_ci FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 9562306a36Sopenharmony_ci { "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024) 9662306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 9762306a36Sopenharmony_ci FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 9862306a36Sopenharmony_ci { "mx66l1g45g", INFO(0xc2201b, 0, 64 * 1024, 2048) 9962306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | 10062306a36Sopenharmony_ci SPI_NOR_QUAD_READ) }, 10162306a36Sopenharmony_ci { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048) 10262306a36Sopenharmony_ci NO_SFDP_FLAGS(SPI_NOR_QUAD_READ) }, 10362306a36Sopenharmony_ci { "mx66u2g45g", INFO(0xc2253c, 0, 64 * 1024, 4096) 10462306a36Sopenharmony_ci NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) 10562306a36Sopenharmony_ci FIXUP_FLAGS(SPI_NOR_4B_OPCODES) }, 10662306a36Sopenharmony_ci}; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic void macronix_nor_default_init(struct spi_nor *nor) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic int macronix_nor_late_init(struct spi_nor *nor) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci if (!nor->params->set_4byte_addr_mode) 11662306a36Sopenharmony_ci nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci return 0; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic const struct spi_nor_fixups macronix_nor_fixups = { 12262306a36Sopenharmony_ci .default_init = macronix_nor_default_init, 12362306a36Sopenharmony_ci .late_init = macronix_nor_late_init, 12462306a36Sopenharmony_ci}; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ciconst struct spi_nor_manufacturer spi_nor_macronix = { 12762306a36Sopenharmony_ci .name = "macronix", 12862306a36Sopenharmony_ci .parts = macronix_nor_parts, 12962306a36Sopenharmony_ci .nparts = ARRAY_SIZE(macronix_nor_parts), 13062306a36Sopenharmony_ci .fixups = ¯onix_nor_fixups, 13162306a36Sopenharmony_ci}; 132