xref: /rk3399_rockchip-uboot/drivers/mtd/spi/spi-nor-tiny.c (revision da74824551f7610aee5c245bae76fe346ca8dab4)
1*da748245SVignesh R // SPDX-License-Identifier: GPL-2.0
2*da748245SVignesh R /*
3*da748245SVignesh R  * Based on m25p80.c, by Mike Lavender (mike@steroidmicros.com), with
4*da748245SVignesh R  * influence from lart.c (Abraham Van Der Merwe) and mtd_dataflash.c
5*da748245SVignesh R  *
6*da748245SVignesh R  * Copyright (C) 2005, Intec Automation Inc.
7*da748245SVignesh R  * Copyright (C) 2014, Freescale Semiconductor, Inc.
8*da748245SVignesh R  *
9*da748245SVignesh R  * Synced from Linux v4.19
10*da748245SVignesh R  */
11*da748245SVignesh R 
12*da748245SVignesh R #include <common.h>
13*da748245SVignesh R #include <linux/err.h>
14*da748245SVignesh R #include <linux/errno.h>
15*da748245SVignesh R #include <linux/log2.h>
16*da748245SVignesh R #include <linux/math64.h>
17*da748245SVignesh R #include <linux/sizes.h>
18*da748245SVignesh R 
19*da748245SVignesh R #include <linux/mtd/mtd.h>
20*da748245SVignesh R #include <linux/mtd/spi-nor.h>
21*da748245SVignesh R #include <spi-mem.h>
22*da748245SVignesh R #include <spi.h>
23*da748245SVignesh R 
24*da748245SVignesh R #include "sf_internal.h"
25*da748245SVignesh R 
26*da748245SVignesh R /* Define max times to check status register before we give up. */
27*da748245SVignesh R 
28*da748245SVignesh R /*
29*da748245SVignesh R  * For everything but full-chip erase; probably could be much smaller, but kept
30*da748245SVignesh R  * around for safety for now
31*da748245SVignesh R  */
32*da748245SVignesh R 
33*da748245SVignesh R #define HZ					CONFIG_SYS_HZ
34*da748245SVignesh R 
35*da748245SVignesh R #define DEFAULT_READY_WAIT_JIFFIES		(40UL * HZ)
36*da748245SVignesh R 
spi_nor_read_write_reg(struct spi_nor * nor,struct spi_mem_op * op,void * buf)37*da748245SVignesh R static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op
38*da748245SVignesh R 		*op, void *buf)
39*da748245SVignesh R {
40*da748245SVignesh R 	if (op->data.dir == SPI_MEM_DATA_IN)
41*da748245SVignesh R 		op->data.buf.in = buf;
42*da748245SVignesh R 	else
43*da748245SVignesh R 		op->data.buf.out = buf;
44*da748245SVignesh R 	return spi_mem_exec_op(nor->spi, op);
45*da748245SVignesh R }
46*da748245SVignesh R 
spi_nor_read_reg(struct spi_nor * nor,u8 code,u8 * val,int len)47*da748245SVignesh R static int spi_nor_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
48*da748245SVignesh R {
49*da748245SVignesh R 	struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(code, 1),
50*da748245SVignesh R 					  SPI_MEM_OP_NO_ADDR,
51*da748245SVignesh R 					  SPI_MEM_OP_NO_DUMMY,
52*da748245SVignesh R 					  SPI_MEM_OP_DATA_IN(len, NULL, 1));
53*da748245SVignesh R 	int ret;
54*da748245SVignesh R 
55*da748245SVignesh R 	ret = spi_nor_read_write_reg(nor, &op, val);
56*da748245SVignesh R 	if (ret < 0)
57*da748245SVignesh R 		dev_dbg(&flash->spimem->spi->dev, "error %d reading %x\n", ret,
58*da748245SVignesh R 			code);
59*da748245SVignesh R 
60*da748245SVignesh R 	return ret;
61*da748245SVignesh R }
62*da748245SVignesh R 
spi_nor_write_reg(struct spi_nor * nor,u8 opcode,u8 * buf,int len)63*da748245SVignesh R static int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
64*da748245SVignesh R {
65*da748245SVignesh R 	struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 1),
66*da748245SVignesh R 					  SPI_MEM_OP_NO_ADDR,
67*da748245SVignesh R 					  SPI_MEM_OP_NO_DUMMY,
68*da748245SVignesh R 					  SPI_MEM_OP_DATA_OUT(len, NULL, 1));
69*da748245SVignesh R 
70*da748245SVignesh R 	return spi_nor_read_write_reg(nor, &op, buf);
71*da748245SVignesh R }
72*da748245SVignesh R 
spi_nor_read_data(struct spi_nor * nor,loff_t from,size_t len,u_char * buf)73*da748245SVignesh R static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len,
74*da748245SVignesh R 				 u_char *buf)
75*da748245SVignesh R {
76*da748245SVignesh R 	struct spi_mem_op op =
77*da748245SVignesh R 			SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 1),
78*da748245SVignesh R 				   SPI_MEM_OP_ADDR(nor->addr_width, from, 1),
79*da748245SVignesh R 				   SPI_MEM_OP_DUMMY(nor->read_dummy, 1),
80*da748245SVignesh R 				   SPI_MEM_OP_DATA_IN(len, buf, 1));
81*da748245SVignesh R 	size_t remaining = len;
82*da748245SVignesh R 	int ret;
83*da748245SVignesh R 
84*da748245SVignesh R 	/* get transfer protocols. */
85*da748245SVignesh R 	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);
86*da748245SVignesh R 	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto);
87*da748245SVignesh R 	op.dummy.buswidth = op.addr.buswidth;
88*da748245SVignesh R 	op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
89*da748245SVignesh R 
90*da748245SVignesh R 	/* convert the dummy cycles to the number of bytes */
91*da748245SVignesh R 	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
92*da748245SVignesh R 
93*da748245SVignesh R 	while (remaining) {
94*da748245SVignesh R 		op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX;
95*da748245SVignesh R 		ret = spi_mem_adjust_op_size(nor->spi, &op);
96*da748245SVignesh R 		if (ret)
97*da748245SVignesh R 			return ret;
98*da748245SVignesh R 
99*da748245SVignesh R 		ret = spi_mem_exec_op(nor->spi, &op);
100*da748245SVignesh R 		if (ret)
101*da748245SVignesh R 			return ret;
102*da748245SVignesh R 
103*da748245SVignesh R 		op.addr.val += op.data.nbytes;
104*da748245SVignesh R 		remaining -= op.data.nbytes;
105*da748245SVignesh R 		op.data.buf.in += op.data.nbytes;
106*da748245SVignesh R 	}
107*da748245SVignesh R 
108*da748245SVignesh R 	return len;
109*da748245SVignesh R }
110*da748245SVignesh R 
111*da748245SVignesh R #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
112*da748245SVignesh R /*
113*da748245SVignesh R  * Read configuration register, returning its value in the
114*da748245SVignesh R  * location. Return the configuration register value.
115*da748245SVignesh R  * Returns negative if error occurred.
116*da748245SVignesh R  */
read_cr(struct spi_nor * nor)117*da748245SVignesh R static int read_cr(struct spi_nor *nor)
118*da748245SVignesh R {
119*da748245SVignesh R 	int ret;
120*da748245SVignesh R 	u8 val;
121*da748245SVignesh R 
122*da748245SVignesh R 	ret = spi_nor_read_reg(nor, SPINOR_OP_RDCR, &val, 1);
123*da748245SVignesh R 	if (ret < 0) {
124*da748245SVignesh R 		dev_dbg(nor->dev, "error %d reading CR\n", ret);
125*da748245SVignesh R 		return ret;
126*da748245SVignesh R 	}
127*da748245SVignesh R 
128*da748245SVignesh R 	return val;
129*da748245SVignesh R }
130*da748245SVignesh R #endif
131*da748245SVignesh R 
132*da748245SVignesh R /*
133*da748245SVignesh R  * Write status register 1 byte
134*da748245SVignesh R  * Returns negative if error occurred.
135*da748245SVignesh R  */
write_sr(struct spi_nor * nor,u8 val)136*da748245SVignesh R static inline int write_sr(struct spi_nor *nor, u8 val)
137*da748245SVignesh R {
138*da748245SVignesh R 	nor->cmd_buf[0] = val;
139*da748245SVignesh R 	return spi_nor_write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1);
140*da748245SVignesh R }
141*da748245SVignesh R 
142*da748245SVignesh R /*
143*da748245SVignesh R  * Set write enable latch with Write Enable command.
144*da748245SVignesh R  * Returns negative if error occurred.
145*da748245SVignesh R  */
write_enable(struct spi_nor * nor)146*da748245SVignesh R static inline int write_enable(struct spi_nor *nor)
147*da748245SVignesh R {
148*da748245SVignesh R 	return spi_nor_write_reg(nor, SPINOR_OP_WREN, NULL, 0);
149*da748245SVignesh R }
150*da748245SVignesh R 
151*da748245SVignesh R /*
152*da748245SVignesh R  * Send write disable instruction to the chip.
153*da748245SVignesh R  */
write_disable(struct spi_nor * nor)154*da748245SVignesh R static inline int write_disable(struct spi_nor *nor)
155*da748245SVignesh R {
156*da748245SVignesh R 	return spi_nor_write_reg(nor, SPINOR_OP_WRDI, NULL, 0);
157*da748245SVignesh R }
158*da748245SVignesh R 
mtd_to_spi_nor(struct mtd_info * mtd)159*da748245SVignesh R static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
160*da748245SVignesh R {
161*da748245SVignesh R 	return mtd->priv;
162*da748245SVignesh R }
163*da748245SVignesh R 
spi_nor_convert_opcode(u8 opcode,const u8 table[][2],size_t size)164*da748245SVignesh R static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
165*da748245SVignesh R {
166*da748245SVignesh R 	size_t i;
167*da748245SVignesh R 
168*da748245SVignesh R 	for (i = 0; i < size; i++)
169*da748245SVignesh R 		if (table[i][0] == opcode)
170*da748245SVignesh R 			return table[i][1];
171*da748245SVignesh R 
172*da748245SVignesh R 	/* No conversion found, keep input op code. */
173*da748245SVignesh R 	return opcode;
174*da748245SVignesh R }
175*da748245SVignesh R 
spi_nor_convert_3to4_read(u8 opcode)176*da748245SVignesh R static inline u8 spi_nor_convert_3to4_read(u8 opcode)
177*da748245SVignesh R {
178*da748245SVignesh R 	static const u8 spi_nor_3to4_read[][2] = {
179*da748245SVignesh R 		{ SPINOR_OP_READ,	SPINOR_OP_READ_4B },
180*da748245SVignesh R 		{ SPINOR_OP_READ_FAST,	SPINOR_OP_READ_FAST_4B },
181*da748245SVignesh R 		{ SPINOR_OP_READ_1_1_2,	SPINOR_OP_READ_1_1_2_4B },
182*da748245SVignesh R 		{ SPINOR_OP_READ_1_2_2,	SPINOR_OP_READ_1_2_2_4B },
183*da748245SVignesh R 		{ SPINOR_OP_READ_1_1_4,	SPINOR_OP_READ_1_1_4_4B },
184*da748245SVignesh R 		{ SPINOR_OP_READ_1_4_4,	SPINOR_OP_READ_1_4_4_4B },
185*da748245SVignesh R 	};
186*da748245SVignesh R 
187*da748245SVignesh R 	return spi_nor_convert_opcode(opcode, spi_nor_3to4_read,
188*da748245SVignesh R 				      ARRAY_SIZE(spi_nor_3to4_read));
189*da748245SVignesh R }
190*da748245SVignesh R 
spi_nor_set_4byte_opcodes(struct spi_nor * nor,const struct flash_info * info)191*da748245SVignesh R static void spi_nor_set_4byte_opcodes(struct spi_nor *nor,
192*da748245SVignesh R 				      const struct flash_info *info)
193*da748245SVignesh R {
194*da748245SVignesh R 	nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode);
195*da748245SVignesh R }
196*da748245SVignesh R 
197*da748245SVignesh R /* Enable/disable 4-byte addressing mode. */
set_4byte(struct spi_nor * nor,const struct flash_info * info,int enable)198*da748245SVignesh R static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
199*da748245SVignesh R 			    int enable)
200*da748245SVignesh R {
201*da748245SVignesh R 	int status;
202*da748245SVignesh R 	bool need_wren = false;
203*da748245SVignesh R 	u8 cmd;
204*da748245SVignesh R 
205*da748245SVignesh R 	switch (JEDEC_MFR(info)) {
206*da748245SVignesh R 	case SNOR_MFR_ST:
207*da748245SVignesh R 	case SNOR_MFR_MICRON:
208*da748245SVignesh R 		/* Some Micron need WREN command; all will accept it */
209*da748245SVignesh R 		need_wren = true;
210*da748245SVignesh R 	case SNOR_MFR_MACRONIX:
211*da748245SVignesh R 	case SNOR_MFR_WINBOND:
212*da748245SVignesh R 		if (need_wren)
213*da748245SVignesh R 			write_enable(nor);
214*da748245SVignesh R 
215*da748245SVignesh R 		cmd = enable ? SPINOR_OP_EN4B : SPINOR_OP_EX4B;
216*da748245SVignesh R 		status = spi_nor_write_reg(nor, cmd, NULL, 0);
217*da748245SVignesh R 		if (need_wren)
218*da748245SVignesh R 			write_disable(nor);
219*da748245SVignesh R 
220*da748245SVignesh R 		if (!status && !enable &&
221*da748245SVignesh R 		    JEDEC_MFR(info) == SNOR_MFR_WINBOND) {
222*da748245SVignesh R 			/*
223*da748245SVignesh R 			 * On Winbond W25Q256FV, leaving 4byte mode causes
224*da748245SVignesh R 			 * the Extended Address Register to be set to 1, so all
225*da748245SVignesh R 			 * 3-byte-address reads come from the second 16M.
226*da748245SVignesh R 			 * We must clear the register to enable normal behavior.
227*da748245SVignesh R 			 */
228*da748245SVignesh R 			write_enable(nor);
229*da748245SVignesh R 			nor->cmd_buf[0] = 0;
230*da748245SVignesh R 			spi_nor_write_reg(nor, SPINOR_OP_WREAR,
231*da748245SVignesh R 					  nor->cmd_buf, 1);
232*da748245SVignesh R 			write_disable(nor);
233*da748245SVignesh R 		}
234*da748245SVignesh R 
235*da748245SVignesh R 		return status;
236*da748245SVignesh R 	default:
237*da748245SVignesh R 		/* Spansion style */
238*da748245SVignesh R 		nor->cmd_buf[0] = enable << 7;
239*da748245SVignesh R 		return spi_nor_write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1);
240*da748245SVignesh R 	}
241*da748245SVignesh R }
242*da748245SVignesh R 
243*da748245SVignesh R #if defined(CONFIG_SPI_FLASH_SPANSION) ||	\
244*da748245SVignesh R 	defined(CONFIG_SPI_FLASH_WINBOND) ||	\
245*da748245SVignesh R 	defined(CONFIG_SPI_FLASH_MACRONIX)
246*da748245SVignesh R /*
247*da748245SVignesh R  * Read the status register, returning its value in the location
248*da748245SVignesh R  * Return the status register value.
249*da748245SVignesh R  * Returns negative if error occurred.
250*da748245SVignesh R  */
read_sr(struct spi_nor * nor)251*da748245SVignesh R static int read_sr(struct spi_nor *nor)
252*da748245SVignesh R {
253*da748245SVignesh R 	int ret;
254*da748245SVignesh R 	u8 val;
255*da748245SVignesh R 
256*da748245SVignesh R 	ret = spi_nor_read_reg(nor, SPINOR_OP_RDSR, &val, 1);
257*da748245SVignesh R 	if (ret < 0) {
258*da748245SVignesh R 		pr_debug("error %d reading SR\n", (int)ret);
259*da748245SVignesh R 		return ret;
260*da748245SVignesh R 	}
261*da748245SVignesh R 
262*da748245SVignesh R 	return val;
263*da748245SVignesh R }
264*da748245SVignesh R 
265*da748245SVignesh R /*
266*da748245SVignesh R  * Read the flag status register, returning its value in the location
267*da748245SVignesh R  * Return the status register value.
268*da748245SVignesh R  * Returns negative if error occurred.
269*da748245SVignesh R  */
read_fsr(struct spi_nor * nor)270*da748245SVignesh R static int read_fsr(struct spi_nor *nor)
271*da748245SVignesh R {
272*da748245SVignesh R 	int ret;
273*da748245SVignesh R 	u8 val;
274*da748245SVignesh R 
275*da748245SVignesh R 	ret = spi_nor_read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
276*da748245SVignesh R 	if (ret < 0) {
277*da748245SVignesh R 		pr_debug("error %d reading FSR\n", ret);
278*da748245SVignesh R 		return ret;
279*da748245SVignesh R 	}
280*da748245SVignesh R 
281*da748245SVignesh R 	return val;
282*da748245SVignesh R }
283*da748245SVignesh R 
spi_nor_sr_ready(struct spi_nor * nor)284*da748245SVignesh R static int spi_nor_sr_ready(struct spi_nor *nor)
285*da748245SVignesh R {
286*da748245SVignesh R 	int sr = read_sr(nor);
287*da748245SVignesh R 
288*da748245SVignesh R 	if (sr < 0)
289*da748245SVignesh R 		return sr;
290*da748245SVignesh R 
291*da748245SVignesh R 	return !(sr & SR_WIP);
292*da748245SVignesh R }
293*da748245SVignesh R 
spi_nor_fsr_ready(struct spi_nor * nor)294*da748245SVignesh R static int spi_nor_fsr_ready(struct spi_nor *nor)
295*da748245SVignesh R {
296*da748245SVignesh R 	int fsr = read_fsr(nor);
297*da748245SVignesh R 
298*da748245SVignesh R 	if (fsr < 0)
299*da748245SVignesh R 		return fsr;
300*da748245SVignesh R 	return fsr & FSR_READY;
301*da748245SVignesh R }
302*da748245SVignesh R 
spi_nor_ready(struct spi_nor * nor)303*da748245SVignesh R static int spi_nor_ready(struct spi_nor *nor)
304*da748245SVignesh R {
305*da748245SVignesh R 	int sr, fsr;
306*da748245SVignesh R 
307*da748245SVignesh R 	sr = spi_nor_sr_ready(nor);
308*da748245SVignesh R 	if (sr < 0)
309*da748245SVignesh R 		return sr;
310*da748245SVignesh R 	fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
311*da748245SVignesh R 	if (fsr < 0)
312*da748245SVignesh R 		return fsr;
313*da748245SVignesh R 	return sr && fsr;
314*da748245SVignesh R }
315*da748245SVignesh R 
316*da748245SVignesh R /*
317*da748245SVignesh R  * Service routine to read status register until ready, or timeout occurs.
318*da748245SVignesh R  * Returns non-zero if error.
319*da748245SVignesh R  */
spi_nor_wait_till_ready_with_timeout(struct spi_nor * nor,unsigned long timeout)320*da748245SVignesh R static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
321*da748245SVignesh R 						unsigned long timeout)
322*da748245SVignesh R {
323*da748245SVignesh R 	unsigned long timebase;
324*da748245SVignesh R 	int ret;
325*da748245SVignesh R 
326*da748245SVignesh R 	timebase = get_timer(0);
327*da748245SVignesh R 
328*da748245SVignesh R 	while (get_timer(timebase) < timeout) {
329*da748245SVignesh R 		ret = spi_nor_ready(nor);
330*da748245SVignesh R 		if (ret < 0)
331*da748245SVignesh R 			return ret;
332*da748245SVignesh R 		if (ret)
333*da748245SVignesh R 			return 0;
334*da748245SVignesh R 	}
335*da748245SVignesh R 
336*da748245SVignesh R 	dev_err(nor->dev, "flash operation timed out\n");
337*da748245SVignesh R 
338*da748245SVignesh R 	return -ETIMEDOUT;
339*da748245SVignesh R }
340*da748245SVignesh R 
spi_nor_wait_till_ready(struct spi_nor * nor)341*da748245SVignesh R static int spi_nor_wait_till_ready(struct spi_nor *nor)
342*da748245SVignesh R {
343*da748245SVignesh R 	return spi_nor_wait_till_ready_with_timeout(nor,
344*da748245SVignesh R 						    DEFAULT_READY_WAIT_JIFFIES);
345*da748245SVignesh R }
346*da748245SVignesh R #endif /* CONFIG_SPI_FLASH_SPANSION */
347*da748245SVignesh R 
348*da748245SVignesh R /*
349*da748245SVignesh R  * Erase an address range on the nor chip.  The address range may extend
350*da748245SVignesh R  * one or more erase sectors.  Return an error is there is a problem erasing.
351*da748245SVignesh R  */
spi_nor_erase(struct mtd_info * mtd,struct erase_info * instr)352*da748245SVignesh R static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
353*da748245SVignesh R {
354*da748245SVignesh R 	return -ENOTSUPP;
355*da748245SVignesh R }
356*da748245SVignesh R 
spi_nor_read_id(struct spi_nor * nor)357*da748245SVignesh R static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
358*da748245SVignesh R {
359*da748245SVignesh R 	int			tmp;
360*da748245SVignesh R 	u8			id[SPI_NOR_MAX_ID_LEN];
361*da748245SVignesh R 	const struct flash_info	*info;
362*da748245SVignesh R 
363*da748245SVignesh R 	tmp = spi_nor_read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
364*da748245SVignesh R 	if (tmp < 0) {
365*da748245SVignesh R 		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
366*da748245SVignesh R 		return ERR_PTR(tmp);
367*da748245SVignesh R 	}
368*da748245SVignesh R 
369*da748245SVignesh R 	info = spi_nor_ids;
370*da748245SVignesh R 	for (; info->sector_size != 0; info++) {
371*da748245SVignesh R 		if (info->id_len) {
372*da748245SVignesh R 			if (!memcmp(info->id, id, info->id_len))
373*da748245SVignesh R 				return info;
374*da748245SVignesh R 		}
375*da748245SVignesh R 	}
376*da748245SVignesh R 	dev_dbg(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
377*da748245SVignesh R 		id[0], id[1], id[2]);
378*da748245SVignesh R 	return ERR_PTR(-ENODEV);
379*da748245SVignesh R }
380*da748245SVignesh R 
spi_nor_read(struct mtd_info * mtd,loff_t from,size_t len,size_t * retlen,u_char * buf)381*da748245SVignesh R static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
382*da748245SVignesh R 			size_t *retlen, u_char *buf)
383*da748245SVignesh R {
384*da748245SVignesh R 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
385*da748245SVignesh R 	int ret;
386*da748245SVignesh R 
387*da748245SVignesh R 	dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
388*da748245SVignesh R 
389*da748245SVignesh R 	while (len) {
390*da748245SVignesh R 		loff_t addr = from;
391*da748245SVignesh R 
392*da748245SVignesh R 		ret = spi_nor_read_data(nor, addr, len, buf);
393*da748245SVignesh R 		if (ret == 0) {
394*da748245SVignesh R 			/* We shouldn't see 0-length reads */
395*da748245SVignesh R 			ret = -EIO;
396*da748245SVignesh R 			goto read_err;
397*da748245SVignesh R 		}
398*da748245SVignesh R 		if (ret < 0)
399*da748245SVignesh R 			goto read_err;
400*da748245SVignesh R 
401*da748245SVignesh R 		*retlen += ret;
402*da748245SVignesh R 		buf += ret;
403*da748245SVignesh R 		from += ret;
404*da748245SVignesh R 		len -= ret;
405*da748245SVignesh R 	}
406*da748245SVignesh R 	ret = 0;
407*da748245SVignesh R 
408*da748245SVignesh R read_err:
409*da748245SVignesh R 	return ret;
410*da748245SVignesh R }
411*da748245SVignesh R 
412*da748245SVignesh R /*
413*da748245SVignesh R  * Write an address range to the nor chip.  Data must be written in
414*da748245SVignesh R  * FLASH_PAGESIZE chunks.  The address range may be any size provided
415*da748245SVignesh R  * it is within the physical boundaries.
416*da748245SVignesh R  */
spi_nor_write(struct mtd_info * mtd,loff_t to,size_t len,size_t * retlen,const u_char * buf)417*da748245SVignesh R static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
418*da748245SVignesh R 			 size_t *retlen, const u_char *buf)
419*da748245SVignesh R {
420*da748245SVignesh R 	return -ENOTSUPP;
421*da748245SVignesh R }
422*da748245SVignesh R 
423*da748245SVignesh R #ifdef CONFIG_SPI_FLASH_MACRONIX
424*da748245SVignesh R /**
425*da748245SVignesh R  * macronix_quad_enable() - set QE bit in Status Register.
426*da748245SVignesh R  * @nor:	pointer to a 'struct spi_nor'
427*da748245SVignesh R  *
428*da748245SVignesh R  * Set the Quad Enable (QE) bit in the Status Register.
429*da748245SVignesh R  *
430*da748245SVignesh R  * bit 6 of the Status Register is the QE bit for Macronix like QSPI memories.
431*da748245SVignesh R  *
432*da748245SVignesh R  * Return: 0 on success, -errno otherwise.
433*da748245SVignesh R  */
macronix_quad_enable(struct spi_nor * nor)434*da748245SVignesh R static int macronix_quad_enable(struct spi_nor *nor)
435*da748245SVignesh R {
436*da748245SVignesh R 	int ret, val;
437*da748245SVignesh R 
438*da748245SVignesh R 	val = read_sr(nor);
439*da748245SVignesh R 	if (val < 0)
440*da748245SVignesh R 		return val;
441*da748245SVignesh R 	if (val & SR_QUAD_EN_MX)
442*da748245SVignesh R 		return 0;
443*da748245SVignesh R 
444*da748245SVignesh R 	write_enable(nor);
445*da748245SVignesh R 
446*da748245SVignesh R 	write_sr(nor, val | SR_QUAD_EN_MX);
447*da748245SVignesh R 
448*da748245SVignesh R 	ret = spi_nor_wait_till_ready(nor);
449*da748245SVignesh R 	if (ret)
450*da748245SVignesh R 		return ret;
451*da748245SVignesh R 
452*da748245SVignesh R 	ret = read_sr(nor);
453*da748245SVignesh R 	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
454*da748245SVignesh R 		dev_err(nor->dev, "Macronix Quad bit not set\n");
455*da748245SVignesh R 		return -EINVAL;
456*da748245SVignesh R 	}
457*da748245SVignesh R 
458*da748245SVignesh R 	return 0;
459*da748245SVignesh R }
460*da748245SVignesh R #endif
461*da748245SVignesh R 
462*da748245SVignesh R #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
463*da748245SVignesh R /*
464*da748245SVignesh R  * Write status Register and configuration register with 2 bytes
465*da748245SVignesh R  * The first byte will be written to the status register, while the
466*da748245SVignesh R  * second byte will be written to the configuration register.
467*da748245SVignesh R  * Return negative if error occurred.
468*da748245SVignesh R  */
write_sr_cr(struct spi_nor * nor,u8 * sr_cr)469*da748245SVignesh R static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
470*da748245SVignesh R {
471*da748245SVignesh R 	int ret;
472*da748245SVignesh R 
473*da748245SVignesh R 	write_enable(nor);
474*da748245SVignesh R 
475*da748245SVignesh R 	ret = spi_nor_write_reg(nor, SPINOR_OP_WRSR, sr_cr, 2);
476*da748245SVignesh R 	if (ret < 0) {
477*da748245SVignesh R 		dev_dbg(nor->dev,
478*da748245SVignesh R 			"error while writing configuration register\n");
479*da748245SVignesh R 		return -EINVAL;
480*da748245SVignesh R 	}
481*da748245SVignesh R 
482*da748245SVignesh R 	ret = spi_nor_wait_till_ready(nor);
483*da748245SVignesh R 	if (ret) {
484*da748245SVignesh R 		dev_dbg(nor->dev,
485*da748245SVignesh R 			"timeout while writing configuration register\n");
486*da748245SVignesh R 		return ret;
487*da748245SVignesh R 	}
488*da748245SVignesh R 
489*da748245SVignesh R 	return 0;
490*da748245SVignesh R }
491*da748245SVignesh R 
492*da748245SVignesh R /**
493*da748245SVignesh R  * spansion_read_cr_quad_enable() - set QE bit in Configuration Register.
494*da748245SVignesh R  * @nor:	pointer to a 'struct spi_nor'
495*da748245SVignesh R  *
496*da748245SVignesh R  * Set the Quad Enable (QE) bit in the Configuration Register.
497*da748245SVignesh R  * This function should be used with QSPI memories supporting the Read
498*da748245SVignesh R  * Configuration Register (35h) instruction.
499*da748245SVignesh R  *
500*da748245SVignesh R  * bit 1 of the Configuration Register is the QE bit for Spansion like QSPI
501*da748245SVignesh R  * memories.
502*da748245SVignesh R  *
503*da748245SVignesh R  * Return: 0 on success, -errno otherwise.
504*da748245SVignesh R  */
spansion_read_cr_quad_enable(struct spi_nor * nor)505*da748245SVignesh R static int spansion_read_cr_quad_enable(struct spi_nor *nor)
506*da748245SVignesh R {
507*da748245SVignesh R 	u8 sr_cr[2];
508*da748245SVignesh R 	int ret;
509*da748245SVignesh R 
510*da748245SVignesh R 	/* Check current Quad Enable bit value. */
511*da748245SVignesh R 	ret = read_cr(nor);
512*da748245SVignesh R 	if (ret < 0) {
513*da748245SVignesh R 		dev_dbg(dev, "error while reading configuration register\n");
514*da748245SVignesh R 		return -EINVAL;
515*da748245SVignesh R 	}
516*da748245SVignesh R 
517*da748245SVignesh R 	if (ret & CR_QUAD_EN_SPAN)
518*da748245SVignesh R 		return 0;
519*da748245SVignesh R 
520*da748245SVignesh R 	sr_cr[1] = ret | CR_QUAD_EN_SPAN;
521*da748245SVignesh R 
522*da748245SVignesh R 	/* Keep the current value of the Status Register. */
523*da748245SVignesh R 	ret = read_sr(nor);
524*da748245SVignesh R 	if (ret < 0) {
525*da748245SVignesh R 		dev_dbg(dev, "error while reading status register\n");
526*da748245SVignesh R 		return -EINVAL;
527*da748245SVignesh R 	}
528*da748245SVignesh R 	sr_cr[0] = ret;
529*da748245SVignesh R 
530*da748245SVignesh R 	ret = write_sr_cr(nor, sr_cr);
531*da748245SVignesh R 	if (ret)
532*da748245SVignesh R 		return ret;
533*da748245SVignesh R 
534*da748245SVignesh R 	/* Read back and check it. */
535*da748245SVignesh R 	ret = read_cr(nor);
536*da748245SVignesh R 	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
537*da748245SVignesh R 		dev_dbg(nor->dev, "Spansion Quad bit not set\n");
538*da748245SVignesh R 		return -EINVAL;
539*da748245SVignesh R 	}
540*da748245SVignesh R 
541*da748245SVignesh R 	return 0;
542*da748245SVignesh R }
543*da748245SVignesh R #endif /* CONFIG_SPI_FLASH_SPANSION */
544*da748245SVignesh R 
545*da748245SVignesh R struct spi_nor_read_command {
546*da748245SVignesh R 	u8			num_mode_clocks;
547*da748245SVignesh R 	u8			num_wait_states;
548*da748245SVignesh R 	u8			opcode;
549*da748245SVignesh R 	enum spi_nor_protocol	proto;
550*da748245SVignesh R };
551*da748245SVignesh R 
552*da748245SVignesh R enum spi_nor_read_command_index {
553*da748245SVignesh R 	SNOR_CMD_READ,
554*da748245SVignesh R 	SNOR_CMD_READ_FAST,
555*da748245SVignesh R 
556*da748245SVignesh R 	/* Quad SPI */
557*da748245SVignesh R 	SNOR_CMD_READ_1_1_4,
558*da748245SVignesh R 
559*da748245SVignesh R 	SNOR_CMD_READ_MAX
560*da748245SVignesh R };
561*da748245SVignesh R 
562*da748245SVignesh R struct spi_nor_flash_parameter {
563*da748245SVignesh R 	struct spi_nor_hwcaps		hwcaps;
564*da748245SVignesh R 	struct spi_nor_read_command	reads[SNOR_CMD_READ_MAX];
565*da748245SVignesh R };
566*da748245SVignesh R 
567*da748245SVignesh R static void
spi_nor_set_read_settings(struct spi_nor_read_command * read,u8 num_mode_clocks,u8 num_wait_states,u8 opcode,enum spi_nor_protocol proto)568*da748245SVignesh R spi_nor_set_read_settings(struct spi_nor_read_command *read,
569*da748245SVignesh R 			  u8 num_mode_clocks,
570*da748245SVignesh R 			  u8 num_wait_states,
571*da748245SVignesh R 			  u8 opcode,
572*da748245SVignesh R 			  enum spi_nor_protocol proto)
573*da748245SVignesh R {
574*da748245SVignesh R 	read->num_mode_clocks = num_mode_clocks;
575*da748245SVignesh R 	read->num_wait_states = num_wait_states;
576*da748245SVignesh R 	read->opcode = opcode;
577*da748245SVignesh R 	read->proto = proto;
578*da748245SVignesh R }
579*da748245SVignesh R 
spi_nor_init_params(struct spi_nor * nor,const struct flash_info * info,struct spi_nor_flash_parameter * params)580*da748245SVignesh R static int spi_nor_init_params(struct spi_nor *nor,
581*da748245SVignesh R 			       const struct flash_info *info,
582*da748245SVignesh R 			       struct spi_nor_flash_parameter *params)
583*da748245SVignesh R {
584*da748245SVignesh R 	/* (Fast) Read settings. */
585*da748245SVignesh R 	params->hwcaps.mask = SNOR_HWCAPS_READ;
586*da748245SVignesh R 	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
587*da748245SVignesh R 				  0, 0, SPINOR_OP_READ,
588*da748245SVignesh R 				  SNOR_PROTO_1_1_1);
589*da748245SVignesh R 
590*da748245SVignesh R 	if (!(info->flags & SPI_NOR_NO_FR)) {
591*da748245SVignesh R 		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
592*da748245SVignesh R 		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
593*da748245SVignesh R 					  0, 8, SPINOR_OP_READ_FAST,
594*da748245SVignesh R 					  SNOR_PROTO_1_1_1);
595*da748245SVignesh R 	}
596*da748245SVignesh R 
597*da748245SVignesh R 	if (info->flags & SPI_NOR_QUAD_READ) {
598*da748245SVignesh R 		params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
599*da748245SVignesh R 		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_1_4],
600*da748245SVignesh R 					  0, 8, SPINOR_OP_READ_1_1_4,
601*da748245SVignesh R 					  SNOR_PROTO_1_1_4);
602*da748245SVignesh R 	}
603*da748245SVignesh R 
604*da748245SVignesh R 	return 0;
605*da748245SVignesh R }
606*da748245SVignesh R 
spi_nor_select_read(struct spi_nor * nor,const struct spi_nor_flash_parameter * params,u32 shared_hwcaps)607*da748245SVignesh R static int spi_nor_select_read(struct spi_nor *nor,
608*da748245SVignesh R 			       const struct spi_nor_flash_parameter *params,
609*da748245SVignesh R 			       u32 shared_hwcaps)
610*da748245SVignesh R {
611*da748245SVignesh R 	int best_match = shared_hwcaps & SNOR_HWCAPS_READ_MASK;
612*da748245SVignesh R 	int cmd;
613*da748245SVignesh R 	const struct spi_nor_read_command *read;
614*da748245SVignesh R 
615*da748245SVignesh R 	if (best_match < 0)
616*da748245SVignesh R 		return -EINVAL;
617*da748245SVignesh R 
618*da748245SVignesh R 	if (best_match & SNOR_HWCAPS_READ_1_1_4)
619*da748245SVignesh R 		cmd = SNOR_CMD_READ_1_1_4;
620*da748245SVignesh R 	else if (best_match & SNOR_HWCAPS_READ_FAST)
621*da748245SVignesh R 		cmd = SNOR_CMD_READ_FAST;
622*da748245SVignesh R 	else
623*da748245SVignesh R 		cmd = SNOR_CMD_READ;
624*da748245SVignesh R 
625*da748245SVignesh R 	read = &params->reads[cmd];
626*da748245SVignesh R 	nor->read_opcode = read->opcode;
627*da748245SVignesh R 	nor->read_proto = read->proto;
628*da748245SVignesh R 
629*da748245SVignesh R 	/*
630*da748245SVignesh R 	 * In the spi-nor framework, we don't need to make the difference
631*da748245SVignesh R 	 * between mode clock cycles and wait state clock cycles.
632*da748245SVignesh R 	 * Indeed, the value of the mode clock cycles is used by a QSPI
633*da748245SVignesh R 	 * flash memory to know whether it should enter or leave its 0-4-4
634*da748245SVignesh R 	 * (Continuous Read / XIP) mode.
635*da748245SVignesh R 	 * eXecution In Place is out of the scope of the mtd sub-system.
636*da748245SVignesh R 	 * Hence we choose to merge both mode and wait state clock cycles
637*da748245SVignesh R 	 * into the so called dummy clock cycles.
638*da748245SVignesh R 	 */
639*da748245SVignesh R 	nor->read_dummy = read->num_mode_clocks + read->num_wait_states;
640*da748245SVignesh R 	return 0;
641*da748245SVignesh R }
642*da748245SVignesh R 
spi_nor_setup(struct spi_nor * nor,const struct flash_info * info,const struct spi_nor_flash_parameter * params,const struct spi_nor_hwcaps * hwcaps)643*da748245SVignesh R static int spi_nor_setup(struct spi_nor *nor, const struct flash_info *info,
644*da748245SVignesh R 			 const struct spi_nor_flash_parameter *params,
645*da748245SVignesh R 			 const struct spi_nor_hwcaps *hwcaps)
646*da748245SVignesh R {
647*da748245SVignesh R 	u32 shared_mask;
648*da748245SVignesh R 	int err;
649*da748245SVignesh R 
650*da748245SVignesh R 	/*
651*da748245SVignesh R 	 * Keep only the hardware capabilities supported by both the SPI
652*da748245SVignesh R 	 * controller and the SPI flash memory.
653*da748245SVignesh R 	 */
654*da748245SVignesh R 	shared_mask = hwcaps->mask & params->hwcaps.mask;
655*da748245SVignesh R 
656*da748245SVignesh R 	/* Select the (Fast) Read command. */
657*da748245SVignesh R 	err = spi_nor_select_read(nor, params, shared_mask);
658*da748245SVignesh R 	if (err) {
659*da748245SVignesh R 		dev_dbg(nor->dev,
660*da748245SVignesh R 			"can't select read settings supported by both the SPI controller and memory.\n");
661*da748245SVignesh R 		return err;
662*da748245SVignesh R 	}
663*da748245SVignesh R 
664*da748245SVignesh R 	/* Enable Quad I/O if needed. */
665*da748245SVignesh R 	if (spi_nor_get_protocol_width(nor->read_proto) == 4) {
666*da748245SVignesh R 		switch (JEDEC_MFR(info)) {
667*da748245SVignesh R #ifdef CONFIG_SPI_FLASH_MACRONIX
668*da748245SVignesh R 		case SNOR_MFR_MACRONIX:
669*da748245SVignesh R 			err = macronix_quad_enable(nor);
670*da748245SVignesh R 			break;
671*da748245SVignesh R #endif
672*da748245SVignesh R 		case SNOR_MFR_ST:
673*da748245SVignesh R 		case SNOR_MFR_MICRON:
674*da748245SVignesh R 			break;
675*da748245SVignesh R 
676*da748245SVignesh R 		default:
677*da748245SVignesh R #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)
678*da748245SVignesh R 			/* Kept only for backward compatibility purpose. */
679*da748245SVignesh R 			err = spansion_read_cr_quad_enable(nor);
680*da748245SVignesh R #endif
681*da748245SVignesh R 			break;
682*da748245SVignesh R 		}
683*da748245SVignesh R 	}
684*da748245SVignesh R 	if (err) {
685*da748245SVignesh R 		dev_dbg(nor->dev, "quad mode not supported\n");
686*da748245SVignesh R 		return err;
687*da748245SVignesh R 	}
688*da748245SVignesh R 
689*da748245SVignesh R 	return 0;
690*da748245SVignesh R }
691*da748245SVignesh R 
spi_nor_init(struct spi_nor * nor)692*da748245SVignesh R static int spi_nor_init(struct spi_nor *nor)
693*da748245SVignesh R {
694*da748245SVignesh R 	if (nor->addr_width == 4 &&
695*da748245SVignesh R 	    (JEDEC_MFR(nor->info) != SNOR_MFR_SPANSION) &&
696*da748245SVignesh R 	    !(nor->info->flags & SPI_NOR_4B_OPCODES)) {
697*da748245SVignesh R 		/*
698*da748245SVignesh R 		 * If the RESET# pin isn't hooked up properly, or the system
699*da748245SVignesh R 		 * otherwise doesn't perform a reset command in the boot
700*da748245SVignesh R 		 * sequence, it's impossible to 100% protect against unexpected
701*da748245SVignesh R 		 * reboots (e.g., crashes). Warn the user (or hopefully, system
702*da748245SVignesh R 		 * designer) that this is bad.
703*da748245SVignesh R 		 */
704*da748245SVignesh R 		if (nor->flags & SNOR_F_BROKEN_RESET)
705*da748245SVignesh R 			printf("enabling reset hack; may not recover from unexpected reboots\n");
706*da748245SVignesh R 		set_4byte(nor, nor->info, 1);
707*da748245SVignesh R 	}
708*da748245SVignesh R 
709*da748245SVignesh R 	return 0;
710*da748245SVignesh R }
711*da748245SVignesh R 
spi_nor_scan(struct spi_nor * nor)712*da748245SVignesh R int spi_nor_scan(struct spi_nor *nor)
713*da748245SVignesh R {
714*da748245SVignesh R 	struct spi_nor_flash_parameter params;
715*da748245SVignesh R 	const struct flash_info *info = NULL;
716*da748245SVignesh R 	struct mtd_info *mtd = &nor->mtd;
717*da748245SVignesh R 	struct spi_nor_hwcaps hwcaps = {
718*da748245SVignesh R 		.mask = SNOR_HWCAPS_READ |
719*da748245SVignesh R 			SNOR_HWCAPS_READ_FAST
720*da748245SVignesh R 	};
721*da748245SVignesh R 	struct spi_slave *spi = nor->spi;
722*da748245SVignesh R 	int ret;
723*da748245SVignesh R 
724*da748245SVignesh R 	/* Reset SPI protocol for all commands. */
725*da748245SVignesh R 	nor->reg_proto = SNOR_PROTO_1_1_1;
726*da748245SVignesh R 	nor->read_proto = SNOR_PROTO_1_1_1;
727*da748245SVignesh R 	nor->write_proto = SNOR_PROTO_1_1_1;
728*da748245SVignesh R 
729*da748245SVignesh R 	if (spi->mode & SPI_RX_QUAD)
730*da748245SVignesh R 		hwcaps.mask |= SNOR_HWCAPS_READ_1_1_4;
731*da748245SVignesh R 
732*da748245SVignesh R 	info = spi_nor_read_id(nor);
733*da748245SVignesh R 	if (IS_ERR_OR_NULL(info))
734*da748245SVignesh R 		return -ENOENT;
735*da748245SVignesh R 	/* Parse the Serial Flash Discoverable Parameters table. */
736*da748245SVignesh R 	ret = spi_nor_init_params(nor, info, &params);
737*da748245SVignesh R 	if (ret)
738*da748245SVignesh R 		return ret;
739*da748245SVignesh R 
740*da748245SVignesh R 	mtd->name = "spi-flash";
741*da748245SVignesh R 	mtd->priv = nor;
742*da748245SVignesh R 	mtd->type = MTD_NORFLASH;
743*da748245SVignesh R 	mtd->writesize = 1;
744*da748245SVignesh R 	mtd->flags = MTD_CAP_NORFLASH;
745*da748245SVignesh R 	mtd->size = info->sector_size * info->n_sectors;
746*da748245SVignesh R 	mtd->_erase = spi_nor_erase;
747*da748245SVignesh R 	mtd->_read = spi_nor_read;
748*da748245SVignesh R 	mtd->_write = spi_nor_write;
749*da748245SVignesh R 
750*da748245SVignesh R 	nor->size = mtd->size;
751*da748245SVignesh R 
752*da748245SVignesh R 	if (info->flags & USE_FSR)
753*da748245SVignesh R 		nor->flags |= SNOR_F_USE_FSR;
754*da748245SVignesh R 	if (info->flags & USE_CLSR)
755*da748245SVignesh R 		nor->flags |= SNOR_F_USE_CLSR;
756*da748245SVignesh R 
757*da748245SVignesh R 	if (info->flags & SPI_NOR_NO_FR)
758*da748245SVignesh R 		params.hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
759*da748245SVignesh R 
760*da748245SVignesh R 	/*
761*da748245SVignesh R 	 * Configure the SPI memory:
762*da748245SVignesh R 	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
763*da748245SVignesh R 	 * - set the number of dummy cycles (mode cycles + wait states).
764*da748245SVignesh R 	 * - set the SPI protocols for register and memory accesses.
765*da748245SVignesh R 	 * - set the Quad Enable bit if needed (required by SPI x-y-4 protos).
766*da748245SVignesh R 	 */
767*da748245SVignesh R 	ret = spi_nor_setup(nor, info, &params, &hwcaps);
768*da748245SVignesh R 	if (ret)
769*da748245SVignesh R 		return ret;
770*da748245SVignesh R 
771*da748245SVignesh R 	if (nor->addr_width) {
772*da748245SVignesh R 		/* already configured from SFDP */
773*da748245SVignesh R 	} else if (info->addr_width) {
774*da748245SVignesh R 		nor->addr_width = info->addr_width;
775*da748245SVignesh R 	} else if (mtd->size > 0x1000000) {
776*da748245SVignesh R 		/* enable 4-byte addressing if the device exceeds 16MiB */
777*da748245SVignesh R 		nor->addr_width = 4;
778*da748245SVignesh R 		if (JEDEC_MFR(info) == SNOR_MFR_SPANSION ||
779*da748245SVignesh R 		    info->flags & SPI_NOR_4B_OPCODES)
780*da748245SVignesh R 			spi_nor_set_4byte_opcodes(nor, info);
781*da748245SVignesh R 	} else {
782*da748245SVignesh R 		nor->addr_width = 3;
783*da748245SVignesh R 	}
784*da748245SVignesh R 
785*da748245SVignesh R 	if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
786*da748245SVignesh R 		dev_dbg(dev, "address width is too large: %u\n",
787*da748245SVignesh R 			nor->addr_width);
788*da748245SVignesh R 		return -EINVAL;
789*da748245SVignesh R 	}
790*da748245SVignesh R 
791*da748245SVignesh R 	/* Send all the required SPI flash commands to initialize device */
792*da748245SVignesh R 	nor->info = info;
793*da748245SVignesh R 	ret = spi_nor_init(nor);
794*da748245SVignesh R 	if (ret)
795*da748245SVignesh R 		return ret;
796*da748245SVignesh R 
797*da748245SVignesh R 	return 0;
798*da748245SVignesh R }
799*da748245SVignesh R 
800*da748245SVignesh R /* U-Boot specific functions, need to extend MTD to support these */
spi_flash_cmd_get_sw_write_prot(struct spi_nor * nor)801*da748245SVignesh R int spi_flash_cmd_get_sw_write_prot(struct spi_nor *nor)
802*da748245SVignesh R {
803*da748245SVignesh R 	return -ENOTSUPP;
804*da748245SVignesh R }
805