xref: /linux/drivers/mtd/spi-nor/spansion.c (revision c441bfb5f2866de71e092c1b9d866a65978dfe1a)
10173c32aSBoris Brezillon // SPDX-License-Identifier: GPL-2.0
20173c32aSBoris Brezillon /*
30173c32aSBoris Brezillon  * Copyright (C) 2005, Intec Automation Inc.
40173c32aSBoris Brezillon  * Copyright (C) 2014, Freescale Semiconductor, Inc.
50173c32aSBoris Brezillon  */
60173c32aSBoris Brezillon 
70173c32aSBoris Brezillon #include <linux/mtd/spi-nor.h>
80173c32aSBoris Brezillon 
90173c32aSBoris Brezillon #include "core.h"
100173c32aSBoris Brezillon 
11c3266af1SPratyush Yadav #define SPINOR_OP_RD_ANY_REG			0x65	/* Read any register */
12c3266af1SPratyush Yadav #define SPINOR_OP_WR_ANY_REG			0x71	/* Write any register */
13c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR2V		0x00800003
14c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24	0xb
15c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR3V		0x00800004
16c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR3V_PGSZ		BIT(4) /* Page size. */
17c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR5V		0x00800006
18c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN	0x3
19c3266af1SPratyush Yadav #define SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS	0
20c3266af1SPratyush Yadav #define SPINOR_OP_CYPRESS_RD_FAST		0xee
21c3266af1SPratyush Yadav 
22c3266af1SPratyush Yadav /**
23c3266af1SPratyush Yadav  * spi_nor_cypress_octal_dtr_enable() - Enable octal DTR on Cypress flashes.
24c3266af1SPratyush Yadav  * @nor:		pointer to a 'struct spi_nor'
25c3266af1SPratyush Yadav  * @enable:              whether to enable or disable Octal DTR
26c3266af1SPratyush Yadav  *
27c3266af1SPratyush Yadav  * This also sets the memory access latency cycles to 24 to allow the flash to
28c3266af1SPratyush Yadav  * run at up to 200MHz.
29c3266af1SPratyush Yadav  *
30c3266af1SPratyush Yadav  * Return: 0 on success, -errno otherwise.
31c3266af1SPratyush Yadav  */
32c3266af1SPratyush Yadav static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool enable)
33c3266af1SPratyush Yadav {
34c3266af1SPratyush Yadav 	struct spi_mem_op op;
35c3266af1SPratyush Yadav 	u8 *buf = nor->bouncebuf;
36c3266af1SPratyush Yadav 	int ret;
37c3266af1SPratyush Yadav 
38c3266af1SPratyush Yadav 	if (enable) {
39c3266af1SPratyush Yadav 		/* Use 24 dummy cycles for memory array reads. */
40c3266af1SPratyush Yadav 		ret = spi_nor_write_enable(nor);
41c3266af1SPratyush Yadav 		if (ret)
42c3266af1SPratyush Yadav 			return ret;
43c3266af1SPratyush Yadav 
44c3266af1SPratyush Yadav 		*buf = SPINOR_REG_CYPRESS_CFR2V_MEMLAT_11_24;
45c3266af1SPratyush Yadav 		op = (struct spi_mem_op)
46c3266af1SPratyush Yadav 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
47c3266af1SPratyush Yadav 				   SPI_MEM_OP_ADDR(3, SPINOR_REG_CYPRESS_CFR2V,
48c3266af1SPratyush Yadav 						   1),
49c3266af1SPratyush Yadav 				   SPI_MEM_OP_NO_DUMMY,
50c3266af1SPratyush Yadav 				   SPI_MEM_OP_DATA_OUT(1, buf, 1));
51c3266af1SPratyush Yadav 
52c3266af1SPratyush Yadav 		ret = spi_mem_exec_op(nor->spimem, &op);
53c3266af1SPratyush Yadav 		if (ret)
54c3266af1SPratyush Yadav 			return ret;
55c3266af1SPratyush Yadav 
56c3266af1SPratyush Yadav 		ret = spi_nor_wait_till_ready(nor);
57c3266af1SPratyush Yadav 		if (ret)
58c3266af1SPratyush Yadav 			return ret;
59c3266af1SPratyush Yadav 
60c3266af1SPratyush Yadav 		nor->read_dummy = 24;
61c3266af1SPratyush Yadav 	}
62c3266af1SPratyush Yadav 
63c3266af1SPratyush Yadav 	/* Set/unset the octal and DTR enable bits. */
64c3266af1SPratyush Yadav 	ret = spi_nor_write_enable(nor);
65c3266af1SPratyush Yadav 	if (ret)
66c3266af1SPratyush Yadav 		return ret;
67c3266af1SPratyush Yadav 
68c3266af1SPratyush Yadav 	if (enable)
69c3266af1SPratyush Yadav 		*buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_EN;
70c3266af1SPratyush Yadav 	else
71c3266af1SPratyush Yadav 		*buf = SPINOR_REG_CYPRESS_CFR5V_OCT_DTR_DS;
72c3266af1SPratyush Yadav 
73c3266af1SPratyush Yadav 	op = (struct spi_mem_op)
74c3266af1SPratyush Yadav 		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1),
75c3266af1SPratyush Yadav 			   SPI_MEM_OP_ADDR(enable ? 3 : 4,
76c3266af1SPratyush Yadav 					   SPINOR_REG_CYPRESS_CFR5V,
77c3266af1SPratyush Yadav 					   1),
78c3266af1SPratyush Yadav 			   SPI_MEM_OP_NO_DUMMY,
79c3266af1SPratyush Yadav 			   SPI_MEM_OP_DATA_OUT(1, buf, 1));
80c3266af1SPratyush Yadav 
81c3266af1SPratyush Yadav 	if (!enable)
82c3266af1SPratyush Yadav 		spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR);
83c3266af1SPratyush Yadav 
84c3266af1SPratyush Yadav 	ret = spi_mem_exec_op(nor->spimem, &op);
85c3266af1SPratyush Yadav 	if (ret)
86c3266af1SPratyush Yadav 		return ret;
87c3266af1SPratyush Yadav 
88c3266af1SPratyush Yadav 	/* Read flash ID to make sure the switch was successful. */
89c3266af1SPratyush Yadav 	op = (struct spi_mem_op)
90c3266af1SPratyush Yadav 		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
91c3266af1SPratyush Yadav 			   SPI_MEM_OP_ADDR(enable ? 4 : 0, 0, 1),
92c3266af1SPratyush Yadav 			   SPI_MEM_OP_DUMMY(enable ? 3 : 0, 1),
93c3266af1SPratyush Yadav 			   SPI_MEM_OP_DATA_IN(round_up(nor->info->id_len, 2),
94c3266af1SPratyush Yadav 					      buf, 1));
95c3266af1SPratyush Yadav 
96c3266af1SPratyush Yadav 	if (enable)
97c3266af1SPratyush Yadav 		spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR);
98c3266af1SPratyush Yadav 
99c3266af1SPratyush Yadav 	ret = spi_mem_exec_op(nor->spimem, &op);
100c3266af1SPratyush Yadav 	if (ret)
101c3266af1SPratyush Yadav 		return ret;
102c3266af1SPratyush Yadav 
103c3266af1SPratyush Yadav 	if (memcmp(buf, nor->info->id, nor->info->id_len))
104c3266af1SPratyush Yadav 		return -EINVAL;
105c3266af1SPratyush Yadav 
106c3266af1SPratyush Yadav 	return 0;
107c3266af1SPratyush Yadav }
108c3266af1SPratyush Yadav 
109c3266af1SPratyush Yadav static void s28hs512t_default_init(struct spi_nor *nor)
110c3266af1SPratyush Yadav {
111c3266af1SPratyush Yadav 	nor->params->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable;
112294cca6cSPratyush Yadav 	nor->params->writesize = 16;
113c3266af1SPratyush Yadav }
114c3266af1SPratyush Yadav 
115c3266af1SPratyush Yadav static void s28hs512t_post_sfdp_fixup(struct spi_nor *nor)
116c3266af1SPratyush Yadav {
117c3266af1SPratyush Yadav 	/*
118c3266af1SPratyush Yadav 	 * On older versions of the flash the xSPI Profile 1.0 table has the
119c3266af1SPratyush Yadav 	 * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
120c3266af1SPratyush Yadav 	 */
121c3266af1SPratyush Yadav 	if (nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
122c3266af1SPratyush Yadav 		nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
123c3266af1SPratyush Yadav 			SPINOR_OP_CYPRESS_RD_FAST;
124c3266af1SPratyush Yadav 
125c3266af1SPratyush Yadav 	/* This flash is also missing the 4-byte Page Program opcode bit. */
126c3266af1SPratyush Yadav 	spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP],
127c3266af1SPratyush Yadav 				SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
128c3266af1SPratyush Yadav 	/*
129c3266af1SPratyush Yadav 	 * Since xSPI Page Program opcode is backward compatible with
130c3266af1SPratyush Yadav 	 * Legacy SPI, use Legacy SPI opcode there as well.
131c3266af1SPratyush Yadav 	 */
132c3266af1SPratyush Yadav 	spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
133c3266af1SPratyush Yadav 				SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
134c3266af1SPratyush Yadav 
135c3266af1SPratyush Yadav 	/*
136c3266af1SPratyush Yadav 	 * The xSPI Profile 1.0 table advertises the number of additional
137c3266af1SPratyush Yadav 	 * address bytes needed for Read Status Register command as 0 but the
138c3266af1SPratyush Yadav 	 * actual value for that is 4.
139c3266af1SPratyush Yadav 	 */
140c3266af1SPratyush Yadav 	nor->params->rdsr_addr_nbytes = 4;
141c3266af1SPratyush Yadav }
142c3266af1SPratyush Yadav 
143c3266af1SPratyush Yadav static int s28hs512t_post_bfpt_fixup(struct spi_nor *nor,
144c3266af1SPratyush Yadav 				     const struct sfdp_parameter_header *bfpt_header,
145*a580293aSTudor Ambarus 				     const struct sfdp_bfpt *bfpt)
146c3266af1SPratyush Yadav {
147c3266af1SPratyush Yadav 	/*
148c3266af1SPratyush Yadav 	 * The BFPT table advertises a 512B page size but the page size is
149c3266af1SPratyush Yadav 	 * actually configurable (with the default being 256B). Read from
150c3266af1SPratyush Yadav 	 * CFR3V[4] and set the correct size.
151c3266af1SPratyush Yadav 	 */
152c3266af1SPratyush Yadav 	struct spi_mem_op op =
153c3266af1SPratyush Yadav 		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1),
154c3266af1SPratyush Yadav 			   SPI_MEM_OP_ADDR(3, SPINOR_REG_CYPRESS_CFR3V, 1),
155c3266af1SPratyush Yadav 			   SPI_MEM_OP_NO_DUMMY,
156c3266af1SPratyush Yadav 			   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
157c3266af1SPratyush Yadav 	int ret;
158c3266af1SPratyush Yadav 
159c3266af1SPratyush Yadav 	ret = spi_mem_exec_op(nor->spimem, &op);
160c3266af1SPratyush Yadav 	if (ret)
161c3266af1SPratyush Yadav 		return ret;
162c3266af1SPratyush Yadav 
163c3266af1SPratyush Yadav 	if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3V_PGSZ)
164*a580293aSTudor Ambarus 		nor->params->page_size = 512;
165c3266af1SPratyush Yadav 	else
166*a580293aSTudor Ambarus 		nor->params->page_size = 256;
167c3266af1SPratyush Yadav 
168c3266af1SPratyush Yadav 	return 0;
169c3266af1SPratyush Yadav }
170c3266af1SPratyush Yadav 
171c3266af1SPratyush Yadav static struct spi_nor_fixups s28hs512t_fixups = {
172c3266af1SPratyush Yadav 	.default_init = s28hs512t_default_init,
173c3266af1SPratyush Yadav 	.post_sfdp = s28hs512t_post_sfdp_fixup,
174c3266af1SPratyush Yadav 	.post_bfpt = s28hs512t_post_bfpt_fixup,
175c3266af1SPratyush Yadav };
176c3266af1SPratyush Yadav 
1775587fa48SSergei Shtylyov static int
1785587fa48SSergei Shtylyov s25fs_s_post_bfpt_fixups(struct spi_nor *nor,
1795587fa48SSergei Shtylyov 			 const struct sfdp_parameter_header *bfpt_header,
180*a580293aSTudor Ambarus 			 const struct sfdp_bfpt *bfpt)
1815587fa48SSergei Shtylyov {
1825587fa48SSergei Shtylyov 	/*
1835587fa48SSergei Shtylyov 	 * The S25FS-S chip family reports 512-byte pages in BFPT but
1845587fa48SSergei Shtylyov 	 * in reality the write buffer still wraps at the safe default
1855587fa48SSergei Shtylyov 	 * of 256 bytes.  Overwrite the page size advertised by BFPT
1865587fa48SSergei Shtylyov 	 * to get the writes working.
1875587fa48SSergei Shtylyov 	 */
188*a580293aSTudor Ambarus 	nor->params->page_size = 256;
1895587fa48SSergei Shtylyov 
1905587fa48SSergei Shtylyov 	return 0;
1915587fa48SSergei Shtylyov }
1925587fa48SSergei Shtylyov 
1935587fa48SSergei Shtylyov static struct spi_nor_fixups s25fs_s_fixups = {
1945587fa48SSergei Shtylyov 	.post_bfpt = s25fs_s_post_bfpt_fixups,
1955587fa48SSergei Shtylyov };
1965587fa48SSergei Shtylyov 
1970173c32aSBoris Brezillon static const struct flash_info spansion_parts[] = {
1980173c32aSBoris Brezillon 	/* Spansion/Cypress -- single (large) sector size only, at least
1990173c32aSBoris Brezillon 	 * for the chips listed here (without boot sectors).
2000173c32aSBoris Brezillon 	 */
2010173c32aSBoris Brezillon 	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64,
2020173c32aSBoris Brezillon 			     SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2030173c32aSBoris Brezillon 	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128,
2040173c32aSBoris Brezillon 			     SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2050173c32aSBoris Brezillon 	{ "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64,
2060173c32aSBoris Brezillon 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2070173c32aSBoris Brezillon 			      USE_CLSR) },
2080173c32aSBoris Brezillon 	{ "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256,
2090173c32aSBoris Brezillon 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2100173c32aSBoris Brezillon 			      USE_CLSR) },
211075fd6dfSTudor Ambarus 	{ "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128,
212954fd81cSTakahiro Kuwano 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
213954fd81cSTakahiro Kuwano 			      USE_CLSR) },
214075fd6dfSTudor Ambarus 	{ "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512,
2150173c32aSBoris Brezillon 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2160173c32aSBoris Brezillon 			      USE_CLSR) },
2170173c32aSBoris Brezillon 	{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
2180173c32aSBoris Brezillon 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2190173c32aSBoris Brezillon 			      SPI_NOR_HAS_LOCK | USE_CLSR) },
220c26d0d87SYicong Yang 	{ "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256,
221c26d0d87SYicong Yang 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)
222c26d0d87SYicong Yang 	  .fixups = &s25fs_s_fixups, },
223075fd6dfSTudor Ambarus 	{ "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128,
224075fd6dfSTudor Ambarus 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
225075fd6dfSTudor Ambarus 			      USE_CLSR) },
226075fd6dfSTudor Ambarus 	{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512,
227075fd6dfSTudor Ambarus 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
228075fd6dfSTudor Ambarus 			      USE_CLSR) },
2290173c32aSBoris Brezillon 	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256,
2305587fa48SSergei Shtylyov 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)
2315587fa48SSergei Shtylyov 	  .fixups = &s25fs_s_fixups, },
2320173c32aSBoris Brezillon 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
2330173c32aSBoris Brezillon 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
2340173c32aSBoris Brezillon 	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64,
2350173c32aSBoris Brezillon 			     SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2360173c32aSBoris Brezillon 			     USE_CLSR) },
2370173c32aSBoris Brezillon 	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256,
2380173c32aSBoris Brezillon 			     SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2390173c32aSBoris Brezillon 			     USE_CLSR) },
2400173c32aSBoris Brezillon 	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
2410173c32aSBoris Brezillon 	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
2420173c32aSBoris Brezillon 	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
2430173c32aSBoris Brezillon 	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
2440173c32aSBoris Brezillon 	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
2450173c32aSBoris Brezillon 	{ "s25fl004k",  INFO(0xef4013,      0,  64 * 1024,   8,
2460173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2470173c32aSBoris Brezillon 	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16,
2480173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2490173c32aSBoris Brezillon 	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32,
2500173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
25199eae48fSRayagonda Kokatanur 	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128,
25299eae48fSRayagonda Kokatanur 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2530173c32aSBoris Brezillon 	{ "s25fl116k",  INFO(0x014015,      0,  64 * 1024,  32,
2540173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
2550173c32aSBoris Brezillon 	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SECT_4K) },
2560173c32aSBoris Brezillon 	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SECT_4K) },
2570173c32aSBoris Brezillon 	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8,
2580173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ) },
2590173c32aSBoris Brezillon 	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16,
2600173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ) },
2610173c32aSBoris Brezillon 	{ "s25fl064l",  INFO(0x016017,      0,  64 * 1024, 128,
2620173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2630173c32aSBoris Brezillon 			     SPI_NOR_4B_OPCODES) },
2640173c32aSBoris Brezillon 	{ "s25fl128l",  INFO(0x016018,      0,  64 * 1024, 256,
2650173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2660173c32aSBoris Brezillon 			     SPI_NOR_4B_OPCODES) },
2670173c32aSBoris Brezillon 	{ "s25fl256l",  INFO(0x016019,      0,  64 * 1024, 512,
2680173c32aSBoris Brezillon 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
2690173c32aSBoris Brezillon 			     SPI_NOR_4B_OPCODES) },
2708a2644d5SSascha Hauer 	{ "cy15x104q",  INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1,
2718a2644d5SSascha Hauer 			      SPI_NOR_NO_ERASE) },
272c3266af1SPratyush Yadav 	{ "s28hs512t",   INFO(0x345b1a,      0, 256 * 1024, 256,
273c3266af1SPratyush Yadav 			     SECT_4K | SPI_NOR_OCTAL_DTR_READ |
274c3266af1SPratyush Yadav 			      SPI_NOR_OCTAL_DTR_PP)
275c3266af1SPratyush Yadav 	  .fixups = &s28hs512t_fixups,
276c3266af1SPratyush Yadav 	},
2770173c32aSBoris Brezillon };
2780173c32aSBoris Brezillon 
2790173c32aSBoris Brezillon static void spansion_post_sfdp_fixups(struct spi_nor *nor)
2800173c32aSBoris Brezillon {
281829ec640STudor Ambarus 	if (nor->params->size <= SZ_16M)
2820173c32aSBoris Brezillon 		return;
2830173c32aSBoris Brezillon 
2840173c32aSBoris Brezillon 	nor->flags |= SNOR_F_4B_OPCODES;
2850173c32aSBoris Brezillon 	/* No small sector erase for 4-byte command set */
2860173c32aSBoris Brezillon 	nor->erase_opcode = SPINOR_OP_SE;
2870173c32aSBoris Brezillon 	nor->mtd.erasesize = nor->info->sector_size;
2880173c32aSBoris Brezillon }
2890173c32aSBoris Brezillon 
2900173c32aSBoris Brezillon static const struct spi_nor_fixups spansion_fixups = {
2910173c32aSBoris Brezillon 	.post_sfdp = spansion_post_sfdp_fixups,
2920173c32aSBoris Brezillon };
2930173c32aSBoris Brezillon 
2940173c32aSBoris Brezillon const struct spi_nor_manufacturer spi_nor_spansion = {
2950173c32aSBoris Brezillon 	.name = "spansion",
2960173c32aSBoris Brezillon 	.parts = spansion_parts,
2970173c32aSBoris Brezillon 	.nparts = ARRAY_SIZE(spansion_parts),
2980173c32aSBoris Brezillon 	.fixups = &spansion_fixups,
2990173c32aSBoris Brezillon };
300