xref: /linux/drivers/mtd/spi-nor/macronix.c (revision 0ce92d548b44649a8de706f9bb9e74a4ed2f18a7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2005, Intec Automation Inc.
4  * Copyright (C) 2014, Freescale Semiconductor, Inc.
5  */
6 
7 #include <linux/mtd/spi-nor.h>
8 
9 #include "core.h"
10 
11 #define MXIC_NOR_OP_RD_CR2	0x71		/* Read configuration register 2 opcode */
12 #define MXIC_NOR_OP_WR_CR2	0x72		/* Write configuration register 2 opcode */
13 #define MXIC_NOR_ADDR_CR2_MODE	0x00000000	/* CR2 address for setting spi/sopi/dopi mode */
14 #define MXIC_NOR_ADDR_CR2_DC	0x00000300	/* CR2 address for setting dummy cycles */
15 #define MXIC_NOR_REG_DOPI_EN	0x2		/* Enable Octal DTR */
16 #define MXIC_NOR_REG_SPI_EN	0x0		/* Enable SPI */
17 
18 /* Convert dummy cycles to bit pattern */
19 #define MXIC_NOR_REG_DC(p) \
20 	((20 - (p)) >> 1)
21 
22 #define MXIC_NOR_WR_CR2(addr, ndata, buf)			\
23 	SPI_MEM_OP(SPI_MEM_OP_CMD(MXIC_NOR_OP_WR_CR2, 0),	\
24 		   SPI_MEM_OP_ADDR(4, addr, 0),			\
25 		   SPI_MEM_OP_NO_DUMMY,				\
26 		   SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
27 
28 static int
29 mx25l25635_post_bfpt_fixups(struct spi_nor *nor,
30 			    const struct sfdp_parameter_header *bfpt_header,
31 			    const struct sfdp_bfpt *bfpt)
32 {
33 	/*
34 	 * MX25L25635F supports 4B opcodes but MX25L25635E does not.
35 	 * Unfortunately, Macronix has re-used the same JEDEC ID for both
36 	 * variants which prevents us from defining a new entry in the parts
37 	 * table.
38 	 * We need a way to differentiate MX25L25635E and MX25L25635F, and it
39 	 * seems that the F version advertises support for Fast Read 4-4-4 in
40 	 * its BFPT table.
41 	 */
42 	if (bfpt->dwords[SFDP_DWORD(5)] & BFPT_DWORD5_FAST_READ_4_4_4)
43 		nor->flags |= SNOR_F_4B_OPCODES;
44 
45 	return 0;
46 }
47 
48 static int
49 macronix_qpp4b_post_sfdp_fixups(struct spi_nor *nor)
50 {
51 	/* PP_1_1_4_4B is supported but missing in 4BAIT. */
52 	struct spi_nor_flash_parameter *params = nor->params;
53 
54 	params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
55 	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
56 				SPINOR_OP_PP_1_1_4_4B, SNOR_PROTO_1_1_4);
57 
58 	return 0;
59 }
60 
61 static int
62 mx25l3255e_late_init_fixups(struct spi_nor *nor)
63 {
64 	struct spi_nor_flash_parameter *params = nor->params;
65 
66 	/*
67 	 * SFDP of MX25L3255E is JESD216, which does not include the Quad
68 	 * Enable bit Requirement in BFPT. As a result, during BFPT parsing,
69 	 * the quad_enable method is not set to spi_nor_sr1_bit6_quad_enable.
70 	 * Therefore, it is necessary to correct this setting by late_init.
71 	 */
72 	params->quad_enable = spi_nor_sr1_bit6_quad_enable;
73 
74 	/*
75 	 * In addition, MX25L3255E also supports 1-4-4 page program in 3-byte
76 	 * address mode. However, since the 3-byte address 1-4-4 page program
77 	 * is not defined in SFDP, it needs to be configured in late_init.
78 	 */
79 	params->hwcaps.mask |= SNOR_HWCAPS_PP_1_4_4;
80 	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_4_4],
81 				SPINOR_OP_PP_1_4_4, SNOR_PROTO_1_4_4);
82 
83 	return 0;
84 }
85 
86 static const struct spi_nor_fixups mx25l25635_fixups = {
87 	.post_bfpt = mx25l25635_post_bfpt_fixups,
88 	.post_sfdp = macronix_qpp4b_post_sfdp_fixups,
89 };
90 
91 static const struct spi_nor_fixups macronix_qpp4b_fixups = {
92 	.post_sfdp = macronix_qpp4b_post_sfdp_fixups,
93 };
94 
95 static const struct spi_nor_fixups mx25l3255e_fixups = {
96 	.late_init = mx25l3255e_late_init_fixups,
97 };
98 
99 static const struct flash_info macronix_nor_parts[] = {
100 	{
101 		.id = SNOR_ID(0xc2, 0x20, 0x10),
102 		.name = "mx25l512e",
103 		.size = SZ_64K,
104 		.no_sfdp_flags = SECT_4K,
105 	}, {
106 		.id = SNOR_ID(0xc2, 0x20, 0x12),
107 		.name = "mx25l2005a",
108 		.size = SZ_256K,
109 		.no_sfdp_flags = SECT_4K,
110 	}, {
111 		.id = SNOR_ID(0xc2, 0x20, 0x13),
112 		.name = "mx25l4005a",
113 		.size = SZ_512K,
114 		.no_sfdp_flags = SECT_4K,
115 	}, {
116 		.id = SNOR_ID(0xc2, 0x20, 0x14),
117 		.name = "mx25l8005",
118 		.size = SZ_1M,
119 	}, {
120 		/* MX25L1606E */
121 		.id = SNOR_ID(0xc2, 0x20, 0x15),
122 	}, {
123 		.id = SNOR_ID(0xc2, 0x20, 0x16),
124 		.name = "mx25l3205d",
125 		.size = SZ_4M,
126 		.no_sfdp_flags = SECT_4K,
127 	}, {
128 		.id = SNOR_ID(0xc2, 0x20, 0x17),
129 		.name = "mx25l6405d",
130 		.size = SZ_8M,
131 		.no_sfdp_flags = SECT_4K,
132 	}, {
133 		/* MX25L12805D */
134 		.id = SNOR_ID(0xc2, 0x20, 0x18),
135 		.flags = SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP,
136 	}, {
137 		/* MX25L25635E, MX25L25645G */
138 		.id = SNOR_ID(0xc2, 0x20, 0x19),
139 		.fixups = &mx25l25635_fixups
140 	}, {
141 		/* MX66L51235F */
142 		.id = SNOR_ID(0xc2, 0x20, 0x1a),
143 		.fixup_flags = SPI_NOR_4B_OPCODES,
144 		.fixups = &macronix_qpp4b_fixups,
145 	}, {
146 		/* MX66L1G45G */
147 		.id = SNOR_ID(0xc2, 0x20, 0x1b),
148 		.fixups = &macronix_qpp4b_fixups,
149 	}, {
150 		/* MX66L2G45G */
151 		.id = SNOR_ID(0xc2, 0x20, 0x1c),
152 		.fixups = &macronix_qpp4b_fixups,
153 	}, {
154 		.id = SNOR_ID(0xc2, 0x23, 0x14),
155 		.name = "mx25v8035f",
156 		.size = SZ_1M,
157 		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
158 	}, {
159 		.id = SNOR_ID(0xc2, 0x25, 0x32),
160 		.name = "mx25u2033e",
161 		.size = SZ_256K,
162 		.no_sfdp_flags = SECT_4K,
163 	}, {
164 		.id = SNOR_ID(0xc2, 0x25, 0x33),
165 		.name = "mx25u4035",
166 		.size = SZ_512K,
167 		.no_sfdp_flags = SECT_4K,
168 	}, {
169 		.id = SNOR_ID(0xc2, 0x25, 0x34),
170 		.name = "mx25u8035",
171 		.size = SZ_1M,
172 		.no_sfdp_flags = SECT_4K,
173 	}, {
174 		.id = SNOR_ID(0xc2, 0x25, 0x36),
175 		.name = "mx25u3235f",
176 		.size = SZ_4M,
177 		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
178 	}, {
179 		.id = SNOR_ID(0xc2, 0x25, 0x37),
180 		.name = "mx25u6435f",
181 		.size = SZ_8M,
182 		.no_sfdp_flags = SECT_4K,
183 	}, {
184 		.id = SNOR_ID(0xc2, 0x25, 0x38),
185 		.name = "mx25u12835f",
186 		.size = SZ_16M,
187 		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
188 	}, {
189 		/* MX25U51245G */
190 		.id = SNOR_ID(0xc2, 0x25, 0x3a),
191 		.fixups = &macronix_qpp4b_fixups,
192 	}, {
193 		/* MX66U1G45G */
194 		.id = SNOR_ID(0xc2, 0x25, 0x3b),
195 		.fixups = &macronix_qpp4b_fixups,
196 	}, {
197 		/* MX66U2G45G */
198 		.id = SNOR_ID(0xc2, 0x25, 0x3c),
199 		.fixups = &macronix_qpp4b_fixups,
200 	}, {
201 		.id = SNOR_ID(0xc2, 0x26, 0x18),
202 		.name = "mx25l12855e",
203 		.size = SZ_16M,
204 	}, {
205 		.id = SNOR_ID(0xc2, 0x26, 0x19),
206 		.name = "mx25l25655e",
207 		.size = SZ_32M,
208 	}, {
209 		.id = SNOR_ID(0xc2, 0x26, 0x1b),
210 		.name = "mx66l1g55g",
211 		.size = SZ_128M,
212 		.no_sfdp_flags = SPI_NOR_QUAD_READ,
213 	}, {
214 		.id = SNOR_ID(0xc2, 0x28, 0x15),
215 		.name = "mx25r1635f",
216 		.size = SZ_2M,
217 		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
218 	}, {
219 		.id = SNOR_ID(0xc2, 0x28, 0x16),
220 		.name = "mx25r3235f",
221 		.size = SZ_4M,
222 		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
223 	}, {
224 		/* MX25UW51245G */
225 		.id = SNOR_ID(0xc2, 0x81, 0x3a),
226 		.n_banks = 4,
227 		.flags = SPI_NOR_RWW,
228 	}, {
229 		/* MX25L3255E */
230 		.id = SNOR_ID(0xc2, 0x9e, 0x16),
231 		.fixups = &mx25l3255e_fixups,
232 	},
233 	/*
234 	 * This spares us of adding new flash entries for flashes that can be
235 	 * initialized solely based on the SFDP data, but still need the
236 	 * manufacturer hooks to set parameters that can't be discovered at SFDP
237 	 * parsing time.
238 	 */
239 	{ .id = SNOR_ID(0xc2) }
240 };
241 
242 static int macronix_nor_octal_dtr_en(struct spi_nor *nor)
243 {
244 	struct spi_mem_op op;
245 	u8 *buf = nor->bouncebuf, i;
246 	int ret;
247 
248 	/* Use dummy cycles which is parse by SFDP and convert to bit pattern. */
249 	buf[0] = MXIC_NOR_REG_DC(nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].num_wait_states);
250 	op = (struct spi_mem_op)MXIC_NOR_WR_CR2(MXIC_NOR_ADDR_CR2_DC, 1, buf);
251 	ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
252 	if (ret)
253 		return ret;
254 
255 	/* Set the octal and DTR enable bits. */
256 	buf[0] = MXIC_NOR_REG_DOPI_EN;
257 	op = (struct spi_mem_op)MXIC_NOR_WR_CR2(MXIC_NOR_ADDR_CR2_MODE, 1, buf);
258 	ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
259 	if (ret)
260 		return ret;
261 
262 	/* Read flash ID to make sure the switch was successful. */
263 	ret = spi_nor_read_id(nor, nor->addr_nbytes, 4, buf,
264 			      SNOR_PROTO_8_8_8_DTR);
265 	if (ret) {
266 		dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
267 		return ret;
268 	}
269 
270 	/* Macronix SPI-NOR flash 8D-8D-8D read ID would get 6 bytes data A-A-B-B-C-C */
271 	for (i = 0; i < nor->info->id->len; i++)
272 		if (buf[i * 2] != buf[(i * 2) + 1] || buf[i * 2] != nor->info->id->bytes[i])
273 			return -EINVAL;
274 
275 	return 0;
276 }
277 
278 static int macronix_nor_octal_dtr_dis(struct spi_nor *nor)
279 {
280 	struct spi_mem_op op;
281 	u8 *buf = nor->bouncebuf;
282 	int ret;
283 
284 	/*
285 	 * The register is 1-byte wide, but 1-byte transactions are not
286 	 * allowed in 8D-8D-8D mode. Since there is no register at the
287 	 * next location, just initialize the value to 0 and let the
288 	 * transaction go on.
289 	 */
290 	buf[0] = MXIC_NOR_REG_SPI_EN;
291 	buf[1] = 0x0;
292 	op = (struct spi_mem_op)MXIC_NOR_WR_CR2(MXIC_NOR_ADDR_CR2_MODE, 2, buf);
293 	ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
294 	if (ret)
295 		return ret;
296 
297 	/* Read flash ID to make sure the switch was successful. */
298 	ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
299 	if (ret) {
300 		dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
301 		return ret;
302 	}
303 
304 	if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
305 		return -EINVAL;
306 
307 	return 0;
308 }
309 
310 static int macronix_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
311 {
312 	return enable ? macronix_nor_octal_dtr_en(nor) : macronix_nor_octal_dtr_dis(nor);
313 }
314 
315 static void macronix_nor_default_init(struct spi_nor *nor)
316 {
317 	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
318 }
319 
320 static int macronix_nor_late_init(struct spi_nor *nor)
321 {
322 	if (!nor->params->set_4byte_addr_mode)
323 		nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode_en4b_ex4b;
324 	nor->params->set_octal_dtr = macronix_nor_set_octal_dtr;
325 
326 	return 0;
327 }
328 
329 static const struct spi_nor_fixups macronix_nor_fixups = {
330 	.default_init = macronix_nor_default_init,
331 	.late_init = macronix_nor_late_init,
332 };
333 
334 const struct spi_nor_manufacturer spi_nor_macronix = {
335 	.name = "macronix",
336 	.parts = macronix_nor_parts,
337 	.nparts = ARRAY_SIZE(macronix_nor_parts),
338 	.fixups = &macronix_nor_fixups,
339 };
340