xref: /linux/drivers/mtd/devices/st_spi_fsm.c (revision 221cff13cacc55b495bac33bf0f79abe59a6f265)
1d90db4a0SLee Jones /*
2d90db4a0SLee Jones  * st_spi_fsm.c	- ST Fast Sequence Mode (FSM) Serial Flash Controller
3d90db4a0SLee Jones  *
4d90db4a0SLee Jones  * Author: Angus Clark <angus.clark@st.com>
5d90db4a0SLee Jones  *
6d90db4a0SLee Jones  * Copyright (C) 2010-2014 STicroelectronics Limited
7d90db4a0SLee Jones  *
8d90db4a0SLee Jones  * JEDEC probe based on drivers/mtd/devices/m25p80.c
9d90db4a0SLee Jones  *
10d90db4a0SLee Jones  * This code is free software; you can redistribute it and/or modify
11d90db4a0SLee Jones  * it under the terms of the GNU General Public License version 2 as
12d90db4a0SLee Jones  * published by the Free Software Foundation.
13d90db4a0SLee Jones  *
14d90db4a0SLee Jones  */
15d90db4a0SLee Jones #include <linux/kernel.h>
16d90db4a0SLee Jones #include <linux/module.h>
17a63984c1SLee Jones #include <linux/regmap.h>
18d90db4a0SLee Jones #include <linux/platform_device.h>
19a63984c1SLee Jones #include <linux/mfd/syscon.h>
20d90db4a0SLee Jones #include <linux/mtd/mtd.h>
21*221cff13SLee Jones #include <linux/mtd/partitions.h>
22d90db4a0SLee Jones #include <linux/sched.h>
23d90db4a0SLee Jones #include <linux/delay.h>
24d90db4a0SLee Jones #include <linux/io.h>
25d90db4a0SLee Jones #include <linux/of.h>
26d90db4a0SLee Jones 
275549fbd5SLee Jones #include "serial_flash_cmds.h"
285549fbd5SLee Jones 
29bc09fb57SLee Jones /*
30bc09fb57SLee Jones  * FSM SPI Controller Registers
31bc09fb57SLee Jones  */
32bc09fb57SLee Jones #define SPI_CLOCKDIV			0x0010
33bc09fb57SLee Jones #define SPI_MODESELECT			0x0018
34bc09fb57SLee Jones #define SPI_CONFIGDATA			0x0020
35bc09fb57SLee Jones #define SPI_STA_MODE_CHANGE		0x0028
36bc09fb57SLee Jones #define SPI_FAST_SEQ_TRANSFER_SIZE	0x0100
37bc09fb57SLee Jones #define SPI_FAST_SEQ_ADD1		0x0104
38bc09fb57SLee Jones #define SPI_FAST_SEQ_ADD2		0x0108
39bc09fb57SLee Jones #define SPI_FAST_SEQ_ADD_CFG		0x010c
40bc09fb57SLee Jones #define SPI_FAST_SEQ_OPC1		0x0110
41bc09fb57SLee Jones #define SPI_FAST_SEQ_OPC2		0x0114
42bc09fb57SLee Jones #define SPI_FAST_SEQ_OPC3		0x0118
43bc09fb57SLee Jones #define SPI_FAST_SEQ_OPC4		0x011c
44bc09fb57SLee Jones #define SPI_FAST_SEQ_OPC5		0x0120
45bc09fb57SLee Jones #define SPI_MODE_BITS			0x0124
46bc09fb57SLee Jones #define SPI_DUMMY_BITS			0x0128
47bc09fb57SLee Jones #define SPI_FAST_SEQ_FLASH_STA_DATA	0x012c
48bc09fb57SLee Jones #define SPI_FAST_SEQ_1			0x0130
49bc09fb57SLee Jones #define SPI_FAST_SEQ_2			0x0134
50bc09fb57SLee Jones #define SPI_FAST_SEQ_3			0x0138
51bc09fb57SLee Jones #define SPI_FAST_SEQ_4			0x013c
52bc09fb57SLee Jones #define SPI_FAST_SEQ_CFG		0x0140
53bc09fb57SLee Jones #define SPI_FAST_SEQ_STA		0x0144
54bc09fb57SLee Jones #define SPI_QUAD_BOOT_SEQ_INIT_1	0x0148
55bc09fb57SLee Jones #define SPI_QUAD_BOOT_SEQ_INIT_2	0x014c
56bc09fb57SLee Jones #define SPI_QUAD_BOOT_READ_SEQ_1	0x0150
57bc09fb57SLee Jones #define SPI_QUAD_BOOT_READ_SEQ_2	0x0154
58bc09fb57SLee Jones #define SPI_PROGRAM_ERASE_TIME		0x0158
59bc09fb57SLee Jones #define SPI_MULT_PAGE_REPEAT_SEQ_1	0x015c
60bc09fb57SLee Jones #define SPI_MULT_PAGE_REPEAT_SEQ_2	0x0160
61bc09fb57SLee Jones #define SPI_STATUS_WR_TIME_REG		0x0164
62bc09fb57SLee Jones #define SPI_FAST_SEQ_DATA_REG		0x0300
63bc09fb57SLee Jones 
64bc09fb57SLee Jones /*
65bc09fb57SLee Jones  * Register: SPI_MODESELECT
66bc09fb57SLee Jones  */
67bc09fb57SLee Jones #define SPI_MODESELECT_CONTIG		0x01
68bc09fb57SLee Jones #define SPI_MODESELECT_FASTREAD		0x02
69bc09fb57SLee Jones #define SPI_MODESELECT_DUALIO		0x04
70bc09fb57SLee Jones #define SPI_MODESELECT_FSM		0x08
71bc09fb57SLee Jones #define SPI_MODESELECT_QUADBOOT		0x10
72bc09fb57SLee Jones 
73bc09fb57SLee Jones /*
74bc09fb57SLee Jones  * Register: SPI_CONFIGDATA
75bc09fb57SLee Jones  */
76bc09fb57SLee Jones #define SPI_CFG_DEVICE_ST		0x1
77bc09fb57SLee Jones #define SPI_CFG_DEVICE_ATMEL		0x4
78bc09fb57SLee Jones #define SPI_CFG_MIN_CS_HIGH(x)		(((x) & 0xfff) << 4)
79bc09fb57SLee Jones #define SPI_CFG_CS_SETUPHOLD(x)		(((x) & 0xff) << 16)
80bc09fb57SLee Jones #define SPI_CFG_DATA_HOLD(x)		(((x) & 0xff) << 24)
81bc09fb57SLee Jones 
8286f309fdSLee Jones #define SPI_CFG_DEFAULT_MIN_CS_HIGH    SPI_CFG_MIN_CS_HIGH(0x0AA)
8386f309fdSLee Jones #define SPI_CFG_DEFAULT_CS_SETUPHOLD   SPI_CFG_CS_SETUPHOLD(0xA0)
8486f309fdSLee Jones #define SPI_CFG_DEFAULT_DATA_HOLD      SPI_CFG_DATA_HOLD(0x00)
8586f309fdSLee Jones 
86bc09fb57SLee Jones /*
87bc09fb57SLee Jones  * Register: SPI_FAST_SEQ_TRANSFER_SIZE
88bc09fb57SLee Jones  */
89bc09fb57SLee Jones #define TRANSFER_SIZE(x)		((x) * 8)
90bc09fb57SLee Jones 
91bc09fb57SLee Jones /*
92bc09fb57SLee Jones  * Register: SPI_FAST_SEQ_ADD_CFG
93bc09fb57SLee Jones  */
94bc09fb57SLee Jones #define ADR_CFG_CYCLES_ADD1(x)		((x) << 0)
95bc09fb57SLee Jones #define ADR_CFG_PADS_1_ADD1		(0x0 << 6)
96bc09fb57SLee Jones #define ADR_CFG_PADS_2_ADD1		(0x1 << 6)
97bc09fb57SLee Jones #define ADR_CFG_PADS_4_ADD1		(0x3 << 6)
98bc09fb57SLee Jones #define ADR_CFG_CSDEASSERT_ADD1		(1   << 8)
99bc09fb57SLee Jones #define ADR_CFG_CYCLES_ADD2(x)		((x) << (0+16))
100bc09fb57SLee Jones #define ADR_CFG_PADS_1_ADD2		(0x0 << (6+16))
101bc09fb57SLee Jones #define ADR_CFG_PADS_2_ADD2		(0x1 << (6+16))
102bc09fb57SLee Jones #define ADR_CFG_PADS_4_ADD2		(0x3 << (6+16))
103bc09fb57SLee Jones #define ADR_CFG_CSDEASSERT_ADD2		(1   << (8+16))
104bc09fb57SLee Jones 
105bc09fb57SLee Jones /*
106bc09fb57SLee Jones  * Register: SPI_FAST_SEQ_n
107bc09fb57SLee Jones  */
108bc09fb57SLee Jones #define SEQ_OPC_OPCODE(x)		((x) << 0)
109bc09fb57SLee Jones #define SEQ_OPC_CYCLES(x)		((x) << 8)
110bc09fb57SLee Jones #define SEQ_OPC_PADS_1			(0x0 << 14)
111bc09fb57SLee Jones #define SEQ_OPC_PADS_2			(0x1 << 14)
112bc09fb57SLee Jones #define SEQ_OPC_PADS_4			(0x3 << 14)
113bc09fb57SLee Jones #define SEQ_OPC_CSDEASSERT		(1   << 16)
114bc09fb57SLee Jones 
115bc09fb57SLee Jones /*
116bc09fb57SLee Jones  * Register: SPI_FAST_SEQ_CFG
117bc09fb57SLee Jones  */
118bc09fb57SLee Jones #define SEQ_CFG_STARTSEQ		(1 << 0)
119bc09fb57SLee Jones #define SEQ_CFG_SWRESET			(1 << 5)
120bc09fb57SLee Jones #define SEQ_CFG_CSDEASSERT		(1 << 6)
121bc09fb57SLee Jones #define SEQ_CFG_READNOTWRITE		(1 << 7)
122bc09fb57SLee Jones #define SEQ_CFG_ERASE			(1 << 8)
123bc09fb57SLee Jones #define SEQ_CFG_PADS_1			(0x0 << 16)
124bc09fb57SLee Jones #define SEQ_CFG_PADS_2			(0x1 << 16)
125bc09fb57SLee Jones #define SEQ_CFG_PADS_4			(0x3 << 16)
126bc09fb57SLee Jones 
127bc09fb57SLee Jones /*
128bc09fb57SLee Jones  * Register: SPI_MODE_BITS
129bc09fb57SLee Jones  */
130bc09fb57SLee Jones #define MODE_DATA(x)			(x & 0xff)
131bc09fb57SLee Jones #define MODE_CYCLES(x)			((x & 0x3f) << 16)
132bc09fb57SLee Jones #define MODE_PADS_1			(0x0 << 22)
133bc09fb57SLee Jones #define MODE_PADS_2			(0x1 << 22)
134bc09fb57SLee Jones #define MODE_PADS_4			(0x3 << 22)
135bc09fb57SLee Jones #define DUMMY_CSDEASSERT		(1   << 24)
136bc09fb57SLee Jones 
137bc09fb57SLee Jones /*
138bc09fb57SLee Jones  * Register: SPI_DUMMY_BITS
139bc09fb57SLee Jones  */
140bc09fb57SLee Jones #define DUMMY_CYCLES(x)			((x & 0x3f) << 16)
141bc09fb57SLee Jones #define DUMMY_PADS_1			(0x0 << 22)
142bc09fb57SLee Jones #define DUMMY_PADS_2			(0x1 << 22)
143bc09fb57SLee Jones #define DUMMY_PADS_4			(0x3 << 22)
144bc09fb57SLee Jones #define DUMMY_CSDEASSERT		(1   << 24)
145bc09fb57SLee Jones 
146bc09fb57SLee Jones /*
147bc09fb57SLee Jones  * Register: SPI_FAST_SEQ_FLASH_STA_DATA
148bc09fb57SLee Jones  */
149bc09fb57SLee Jones #define STA_DATA_BYTE1(x)		((x & 0xff) << 0)
150bc09fb57SLee Jones #define STA_DATA_BYTE2(x)		((x & 0xff) << 8)
151bc09fb57SLee Jones #define STA_PADS_1			(0x0 << 16)
152bc09fb57SLee Jones #define STA_PADS_2			(0x1 << 16)
153bc09fb57SLee Jones #define STA_PADS_4			(0x3 << 16)
154bc09fb57SLee Jones #define STA_CSDEASSERT			(0x1 << 20)
155bc09fb57SLee Jones #define STA_RDNOTWR			(0x1 << 21)
156bc09fb57SLee Jones 
157bc09fb57SLee Jones /*
158bc09fb57SLee Jones  * FSM SPI Instruction Opcodes
159bc09fb57SLee Jones  */
160bc09fb57SLee Jones #define STFSM_OPC_CMD			0x1
161bc09fb57SLee Jones #define STFSM_OPC_ADD			0x2
162bc09fb57SLee Jones #define STFSM_OPC_STA			0x3
163bc09fb57SLee Jones #define STFSM_OPC_MODE			0x4
164bc09fb57SLee Jones #define STFSM_OPC_DUMMY		0x5
165bc09fb57SLee Jones #define STFSM_OPC_DATA			0x6
166bc09fb57SLee Jones #define STFSM_OPC_WAIT			0x7
167bc09fb57SLee Jones #define STFSM_OPC_JUMP			0x8
168bc09fb57SLee Jones #define STFSM_OPC_GOTO			0x9
169bc09fb57SLee Jones #define STFSM_OPC_STOP			0xF
170bc09fb57SLee Jones 
171bc09fb57SLee Jones /*
172bc09fb57SLee Jones  * FSM SPI Instructions (== opcode + operand).
173bc09fb57SLee Jones  */
174bc09fb57SLee Jones #define STFSM_INSTR(cmd, op)		((cmd) | ((op) << 4))
175bc09fb57SLee Jones 
176bc09fb57SLee Jones #define STFSM_INST_CMD1			STFSM_INSTR(STFSM_OPC_CMD,	1)
177bc09fb57SLee Jones #define STFSM_INST_CMD2			STFSM_INSTR(STFSM_OPC_CMD,	2)
178bc09fb57SLee Jones #define STFSM_INST_CMD3			STFSM_INSTR(STFSM_OPC_CMD,	3)
179bc09fb57SLee Jones #define STFSM_INST_CMD4			STFSM_INSTR(STFSM_OPC_CMD,	4)
180bc09fb57SLee Jones #define STFSM_INST_CMD5			STFSM_INSTR(STFSM_OPC_CMD,	5)
181bc09fb57SLee Jones #define STFSM_INST_ADD1			STFSM_INSTR(STFSM_OPC_ADD,	1)
182bc09fb57SLee Jones #define STFSM_INST_ADD2			STFSM_INSTR(STFSM_OPC_ADD,	2)
183bc09fb57SLee Jones 
184bc09fb57SLee Jones #define STFSM_INST_DATA_WRITE		STFSM_INSTR(STFSM_OPC_DATA,	1)
185bc09fb57SLee Jones #define STFSM_INST_DATA_READ		STFSM_INSTR(STFSM_OPC_DATA,	2)
186bc09fb57SLee Jones 
187bc09fb57SLee Jones #define STFSM_INST_STA_RD1		STFSM_INSTR(STFSM_OPC_STA,	0x1)
188bc09fb57SLee Jones #define STFSM_INST_STA_WR1		STFSM_INSTR(STFSM_OPC_STA,	0x1)
189bc09fb57SLee Jones #define STFSM_INST_STA_RD2		STFSM_INSTR(STFSM_OPC_STA,	0x2)
190bc09fb57SLee Jones #define STFSM_INST_STA_WR1_2		STFSM_INSTR(STFSM_OPC_STA,	0x3)
191bc09fb57SLee Jones 
192bc09fb57SLee Jones #define STFSM_INST_MODE			STFSM_INSTR(STFSM_OPC_MODE,	0)
193bc09fb57SLee Jones #define STFSM_INST_DUMMY		STFSM_INSTR(STFSM_OPC_DUMMY,	0)
194bc09fb57SLee Jones #define STFSM_INST_WAIT			STFSM_INSTR(STFSM_OPC_WAIT,	0)
195bc09fb57SLee Jones #define STFSM_INST_STOP			STFSM_INSTR(STFSM_OPC_STOP,	0)
196bc09fb57SLee Jones 
19786f309fdSLee Jones #define STFSM_DEFAULT_EMI_FREQ 100000000UL                        /* 100 MHz */
19886f309fdSLee Jones #define STFSM_DEFAULT_WR_TIME  (STFSM_DEFAULT_EMI_FREQ * (15/1000)) /* 15ms */
19986f309fdSLee Jones 
20086f309fdSLee Jones #define STFSM_FLASH_SAFE_FREQ  10000000UL                         /* 10 MHz */
20186f309fdSLee Jones 
2023c8b85b3SLee Jones #define STFSM_MAX_WAIT_SEQ_MS  1000     /* FSM execution time */
2033c8b85b3SLee Jones 
204e85a6196SLee Jones /* Flash Commands */
205e85a6196SLee Jones #define FLASH_CMD_WREN         0x06
206e85a6196SLee Jones #define FLASH_CMD_WRDI         0x04
207e85a6196SLee Jones #define FLASH_CMD_RDID         0x9f
208e85a6196SLee Jones #define FLASH_CMD_RDSR         0x05
209e85a6196SLee Jones #define FLASH_CMD_RDSR2                0x35
210e85a6196SLee Jones #define FLASH_CMD_WRSR         0x01
211e85a6196SLee Jones #define FLASH_CMD_SE_4K                0x20
212e85a6196SLee Jones #define FLASH_CMD_SE_32K       0x52
213e85a6196SLee Jones #define FLASH_CMD_SE           0xd8
214e85a6196SLee Jones #define FLASH_CMD_CHIPERASE    0xc7
215e85a6196SLee Jones #define FLASH_CMD_WRVCR                0x81
216e85a6196SLee Jones #define FLASH_CMD_RDVCR                0x85
217e85a6196SLee Jones 
218e85a6196SLee Jones #define FLASH_CMD_READ         0x03    /* READ */
219e85a6196SLee Jones #define FLASH_CMD_READ_FAST    0x0b    /* FAST READ */
220e85a6196SLee Jones #define FLASH_CMD_READ_1_1_2   0x3b    /* DUAL OUTPUT READ */
221e85a6196SLee Jones #define FLASH_CMD_READ_1_2_2   0xbb    /* DUAL I/O READ */
222e85a6196SLee Jones #define FLASH_CMD_READ_1_1_4   0x6b    /* QUAD OUTPUT READ */
223e85a6196SLee Jones #define FLASH_CMD_READ_1_4_4   0xeb    /* QUAD I/O READ */
224e85a6196SLee Jones 
225e85a6196SLee Jones #define FLASH_CMD_WRITE                0x02    /* PAGE PROGRAM */
226e85a6196SLee Jones #define FLASH_CMD_WRITE_1_1_2  0xa2    /* DUAL INPUT PROGRAM */
227e85a6196SLee Jones #define FLASH_CMD_WRITE_1_2_2  0xd2    /* DUAL INPUT EXT PROGRAM */
228e85a6196SLee Jones #define FLASH_CMD_WRITE_1_1_4  0x32    /* QUAD INPUT PROGRAM */
229e85a6196SLee Jones #define FLASH_CMD_WRITE_1_4_4  0x12    /* QUAD INPUT EXT PROGRAM */
230e85a6196SLee Jones 
231e85a6196SLee Jones #define FLASH_CMD_EN4B_ADDR    0xb7    /* Enter 4-byte address mode */
232e85a6196SLee Jones #define FLASH_CMD_EX4B_ADDR    0xe9    /* Exit 4-byte address mode */
233e85a6196SLee Jones 
234e85a6196SLee Jones /* READ commands with 32-bit addressing (N25Q256 and S25FLxxxS) */
235e85a6196SLee Jones #define FLASH_CMD_READ4                0x13
236e85a6196SLee Jones #define FLASH_CMD_READ4_FAST   0x0c
237e85a6196SLee Jones #define FLASH_CMD_READ4_1_1_2  0x3c
238e85a6196SLee Jones #define FLASH_CMD_READ4_1_2_2  0xbc
239e85a6196SLee Jones #define FLASH_CMD_READ4_1_1_4  0x6c
240e85a6196SLee Jones #define FLASH_CMD_READ4_1_4_4  0xec
241e85a6196SLee Jones 
2425343a123SLee Jones /* S25FLxxxS commands */
2435343a123SLee Jones #define S25FL_CMD_WRITE4_1_1_4 0x34
2445343a123SLee Jones #define S25FL_CMD_SE4          0xdc
2455343a123SLee Jones #define S25FL_CMD_CLSR         0x30
2465343a123SLee Jones #define S25FL_CMD_DYBWR                0xe1
2475343a123SLee Jones #define S25FL_CMD_DYBRD                0xe0
2485343a123SLee Jones #define S25FL_CMD_WRITE4       0x12    /* Note, opcode clashes with
2495343a123SLee Jones 					* 'FLASH_CMD_WRITE_1_4_4'
2505343a123SLee Jones 					* as found on N25Qxxx devices! */
2515343a123SLee Jones 
252176b4377SLee Jones /* Status register */
253176b4377SLee Jones #define FLASH_STATUS_BUSY      0x01
254176b4377SLee Jones #define FLASH_STATUS_WEL       0x02
255176b4377SLee Jones #define FLASH_STATUS_BP0       0x04
256176b4377SLee Jones #define FLASH_STATUS_BP1       0x08
257176b4377SLee Jones #define FLASH_STATUS_BP2       0x10
258176b4377SLee Jones #define FLASH_STATUS_SRWP0     0x80
259176b4377SLee Jones #define FLASH_STATUS_TIMEOUT   0xff
2605343a123SLee Jones /* S25FL Error Flags */
2615343a123SLee Jones #define S25FL_STATUS_E_ERR     0x20
2625343a123SLee Jones #define S25FL_STATUS_P_ERR     0x40
263176b4377SLee Jones 
264e514f105SLee Jones #define FLASH_PAGESIZE         256			/* In Bytes    */
265e514f105SLee Jones #define FLASH_PAGESIZE_32      (FLASH_PAGESIZE / 4)	/* In uint32_t */
266176b4377SLee Jones #define FLASH_MAX_BUSY_WAIT    (300 * HZ)	/* Maximum 'CHIPERASE' time */
267e514f105SLee Jones 
268e85a6196SLee Jones /*
269e85a6196SLee Jones  * Flags to tweak operation of default read/write/erase routines
270e85a6196SLee Jones  */
271e85a6196SLee Jones #define CFG_READ_TOGGLE_32BIT_ADDR     0x00000001
272e85a6196SLee Jones #define CFG_WRITE_TOGGLE_32BIT_ADDR    0x00000002
273e85a6196SLee Jones #define CFG_WRITE_EX_32BIT_ADDR_DELAY  0x00000004
274e85a6196SLee Jones #define CFG_ERASESEC_TOGGLE_32BIT_ADDR 0x00000008
275e85a6196SLee Jones #define CFG_S25FL_CHECK_ERROR_FLAGS    0x00000010
276e85a6196SLee Jones 
277e6b1bb4eSLee Jones struct stfsm_seq {
278e6b1bb4eSLee Jones 	uint32_t data_size;
279e6b1bb4eSLee Jones 	uint32_t addr1;
280e6b1bb4eSLee Jones 	uint32_t addr2;
281e6b1bb4eSLee Jones 	uint32_t addr_cfg;
282e6b1bb4eSLee Jones 	uint32_t seq_opc[5];
283e6b1bb4eSLee Jones 	uint32_t mode;
284e6b1bb4eSLee Jones 	uint32_t dummy;
285e6b1bb4eSLee Jones 	uint32_t status;
286e6b1bb4eSLee Jones 	uint8_t  seq[16];
287e6b1bb4eSLee Jones 	uint32_t seq_cfg;
288e6b1bb4eSLee Jones } __packed __aligned(4);
289e6b1bb4eSLee Jones 
290d90db4a0SLee Jones struct stfsm {
291d90db4a0SLee Jones 	struct device		*dev;
292d90db4a0SLee Jones 	void __iomem		*base;
293d90db4a0SLee Jones 	struct resource		*region;
294d90db4a0SLee Jones 	struct mtd_info		mtd;
295d90db4a0SLee Jones 	struct mutex		lock;
29624fec651SLee Jones 	struct flash_info       *info;
29786f309fdSLee Jones 
298e85a6196SLee Jones 	uint32_t                configuration;
29986f309fdSLee Jones 	uint32_t                fifo_dir_delay;
300a63984c1SLee Jones 	bool                    booted_from_spi;
3010ea7d706SLee Jones 	bool                    reset_signal;
3020ea7d706SLee Jones 	bool                    reset_por;
303d90db4a0SLee Jones 
304e6b1bb4eSLee Jones 	struct stfsm_seq stfsm_seq_read;
305e6b1bb4eSLee Jones 	struct stfsm_seq stfsm_seq_write;
306e6b1bb4eSLee Jones 	struct stfsm_seq stfsm_seq_en_32bit_addr;
307e6b1bb4eSLee Jones };
3083c8b85b3SLee Jones 
30908981274SLee Jones /* Parameters to configure a READ or WRITE FSM sequence */
31008981274SLee Jones struct seq_rw_config {
31108981274SLee Jones 	uint32_t        flags;          /* flags to support config */
31208981274SLee Jones 	uint8_t         cmd;            /* FLASH command */
31308981274SLee Jones 	int             write;          /* Write Sequence */
31408981274SLee Jones 	uint8_t         addr_pads;      /* No. of addr pads (MODE & DUMMY) */
31508981274SLee Jones 	uint8_t         data_pads;      /* No. of data pads */
31608981274SLee Jones 	uint8_t         mode_data;      /* MODE data */
31708981274SLee Jones 	uint8_t         mode_cycles;    /* No. of MODE cycles */
31808981274SLee Jones 	uint8_t         dummy_cycles;   /* No. of DUMMY cycles */
31908981274SLee Jones };
32008981274SLee Jones 
32111d7f826SLee Jones /* SPI Flash Device Table */
32211d7f826SLee Jones struct flash_info {
32311d7f826SLee Jones 	char            *name;
32411d7f826SLee Jones 	/*
32511d7f826SLee Jones 	 * JEDEC id zero means "no ID" (most older chips); otherwise it has
32611d7f826SLee Jones 	 * a high byte of zero plus three data bytes: the manufacturer id,
32711d7f826SLee Jones 	 * then a two byte device id.
32811d7f826SLee Jones 	 */
32911d7f826SLee Jones 	u32             jedec_id;
33011d7f826SLee Jones 	u16             ext_id;
33111d7f826SLee Jones 	/*
33211d7f826SLee Jones 	 * The size listed here is what works with FLASH_CMD_SE, which isn't
33311d7f826SLee Jones 	 * necessarily called a "sector" by the vendor.
33411d7f826SLee Jones 	 */
33511d7f826SLee Jones 	unsigned        sector_size;
33611d7f826SLee Jones 	u16             n_sectors;
33711d7f826SLee Jones 	u32             flags;
33811d7f826SLee Jones 	/*
33911d7f826SLee Jones 	 * Note, where FAST_READ is supported, freq_max specifies the
34011d7f826SLee Jones 	 * FAST_READ frequency, not the READ frequency.
34111d7f826SLee Jones 	 */
34211d7f826SLee Jones 	u32             max_freq;
34311d7f826SLee Jones 	int             (*config)(struct stfsm *);
34411d7f826SLee Jones };
34511d7f826SLee Jones 
346218b870fSLee Jones static int stfsm_n25q_config(struct stfsm *fsm);
34789818066SLee Jones static int stfsm_mx25_config(struct stfsm *fsm);
3485343a123SLee Jones static int stfsm_s25fl_config(struct stfsm *fsm);
349cd7cac9eSLee Jones static int stfsm_w25q_config(struct stfsm *fsm);
350218b870fSLee Jones 
35111d7f826SLee Jones static struct flash_info flash_types[] = {
35211d7f826SLee Jones 	/*
35311d7f826SLee Jones 	 * ST Microelectronics/Numonyx --
35411d7f826SLee Jones 	 * (newer production versions may have feature updates
35511d7f826SLee Jones 	 * (eg faster operating frequency)
35611d7f826SLee Jones 	 */
35711d7f826SLee Jones #define M25P_FLAG (FLASH_FLAG_READ_WRITE | FLASH_FLAG_READ_FAST)
35811d7f826SLee Jones 	{ "m25p40",  0x202013, 0,  64 * 1024,   8, M25P_FLAG, 25, NULL },
35911d7f826SLee Jones 	{ "m25p80",  0x202014, 0,  64 * 1024,  16, M25P_FLAG, 25, NULL },
36011d7f826SLee Jones 	{ "m25p16",  0x202015, 0,  64 * 1024,  32, M25P_FLAG, 25, NULL },
36111d7f826SLee Jones 	{ "m25p32",  0x202016, 0,  64 * 1024,  64, M25P_FLAG, 50, NULL },
36211d7f826SLee Jones 	{ "m25p64",  0x202017, 0,  64 * 1024, 128, M25P_FLAG, 50, NULL },
36311d7f826SLee Jones 	{ "m25p128", 0x202018, 0, 256 * 1024,  64, M25P_FLAG, 50, NULL },
36411d7f826SLee Jones 
36511d7f826SLee Jones #define M25PX_FLAG (FLASH_FLAG_READ_WRITE      |	\
36611d7f826SLee Jones 		    FLASH_FLAG_READ_FAST        |	\
36711d7f826SLee Jones 		    FLASH_FLAG_READ_1_1_2       |	\
36811d7f826SLee Jones 		    FLASH_FLAG_WRITE_1_1_2)
36911d7f826SLee Jones 	{ "m25px32", 0x207116, 0,  64 * 1024,  64, M25PX_FLAG, 75, NULL },
37011d7f826SLee Jones 	{ "m25px64", 0x207117, 0,  64 * 1024, 128, M25PX_FLAG, 75, NULL },
37111d7f826SLee Jones 
37211d7f826SLee Jones #define MX25_FLAG (FLASH_FLAG_READ_WRITE       |	\
37311d7f826SLee Jones 		   FLASH_FLAG_READ_FAST         |	\
37411d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_2        |	\
37511d7f826SLee Jones 		   FLASH_FLAG_READ_1_2_2        |	\
37611d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_4        |	\
37711d7f826SLee Jones 		   FLASH_FLAG_READ_1_4_4        |	\
37811d7f826SLee Jones 		   FLASH_FLAG_SE_4K             |	\
37911d7f826SLee Jones 		   FLASH_FLAG_SE_32K)
38011d7f826SLee Jones 	{ "mx25l25635e", 0xc22019, 0, 64*1024, 512,
38189818066SLee Jones 	  (MX25_FLAG | FLASH_FLAG_32BIT_ADDR | FLASH_FLAG_RESET), 70,
38289818066SLee Jones 	  stfsm_mx25_config },
38311d7f826SLee Jones 
38411d7f826SLee Jones #define N25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
38511d7f826SLee Jones 		   FLASH_FLAG_READ_FAST         |	\
38611d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_2        |	\
38711d7f826SLee Jones 		   FLASH_FLAG_READ_1_2_2        |	\
38811d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_4        |	\
38911d7f826SLee Jones 		   FLASH_FLAG_READ_1_4_4        |	\
39011d7f826SLee Jones 		   FLASH_FLAG_WRITE_1_1_2       |	\
39111d7f826SLee Jones 		   FLASH_FLAG_WRITE_1_2_2       |	\
39211d7f826SLee Jones 		   FLASH_FLAG_WRITE_1_1_4       |	\
39311d7f826SLee Jones 		   FLASH_FLAG_WRITE_1_4_4)
394218b870fSLee Jones 	{ "n25q128", 0x20ba18, 0, 64 * 1024,  256, N25Q_FLAG, 108,
395218b870fSLee Jones 	  stfsm_n25q_config },
39611d7f826SLee Jones 	{ "n25q256", 0x20ba19, 0, 64 * 1024,  512,
397218b870fSLee Jones 	  N25Q_FLAG | FLASH_FLAG_32BIT_ADDR, 108, stfsm_n25q_config },
39811d7f826SLee Jones 
39911d7f826SLee Jones 	/*
40011d7f826SLee Jones 	 * Spansion S25FLxxxP
40111d7f826SLee Jones 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
40211d7f826SLee Jones 	 */
40311d7f826SLee Jones #define S25FLXXXP_FLAG (FLASH_FLAG_READ_WRITE  |	\
40411d7f826SLee Jones 			FLASH_FLAG_READ_1_1_2   |	\
40511d7f826SLee Jones 			FLASH_FLAG_READ_1_2_2   |	\
40611d7f826SLee Jones 			FLASH_FLAG_READ_1_1_4   |	\
40711d7f826SLee Jones 			FLASH_FLAG_READ_1_4_4   |	\
40811d7f826SLee Jones 			FLASH_FLAG_WRITE_1_1_4  |	\
40911d7f826SLee Jones 			FLASH_FLAG_READ_FAST)
41011d7f826SLee Jones 	{ "s25fl129p0", 0x012018, 0x4d00, 256 * 1024,  64, S25FLXXXP_FLAG, 80,
4115343a123SLee Jones 	  stfsm_s25fl_config },
41211d7f826SLee Jones 	{ "s25fl129p1", 0x012018, 0x4d01,  64 * 1024, 256, S25FLXXXP_FLAG, 80,
4135343a123SLee Jones 	  stfsm_s25fl_config },
41411d7f826SLee Jones 
41511d7f826SLee Jones 	/*
41611d7f826SLee Jones 	 * Spansion S25FLxxxS
41711d7f826SLee Jones 	 *     - 256KiB and 64KiB sector variants (identified by ext. JEDEC)
41811d7f826SLee Jones 	 *     - RESET# signal supported by die but not bristled out on all
41911d7f826SLee Jones 	 *       package types.  The package type is a function of board design,
42011d7f826SLee Jones 	 *       so this information is captured in the board's flags.
42111d7f826SLee Jones 	 *     - Supports 'DYB' sector protection. Depending on variant, sectors
42211d7f826SLee Jones 	 *       may default to locked state on power-on.
42311d7f826SLee Jones 	 */
42411d7f826SLee Jones #define S25FLXXXS_FLAG (S25FLXXXP_FLAG         |	\
42511d7f826SLee Jones 			FLASH_FLAG_RESET        |	\
42611d7f826SLee Jones 			FLASH_FLAG_DYB_LOCKING)
42711d7f826SLee Jones 	{ "s25fl128s0", 0x012018, 0x0300,  256 * 1024, 64, S25FLXXXS_FLAG, 80,
4285343a123SLee Jones 	  stfsm_s25fl_config },
42911d7f826SLee Jones 	{ "s25fl128s1", 0x012018, 0x0301,  64 * 1024, 256, S25FLXXXS_FLAG, 80,
4305343a123SLee Jones 	  stfsm_s25fl_config },
43111d7f826SLee Jones 	{ "s25fl256s0", 0x010219, 0x4d00, 256 * 1024, 128,
4325343a123SLee Jones 	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
43311d7f826SLee Jones 	{ "s25fl256s1", 0x010219, 0x4d01,  64 * 1024, 512,
4345343a123SLee Jones 	  S25FLXXXS_FLAG | FLASH_FLAG_32BIT_ADDR, 80, stfsm_s25fl_config },
43511d7f826SLee Jones 
43611d7f826SLee Jones 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
43711d7f826SLee Jones #define W25X_FLAG (FLASH_FLAG_READ_WRITE       |	\
43811d7f826SLee Jones 		   FLASH_FLAG_READ_FAST         |	\
43911d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_2        |	\
44011d7f826SLee Jones 		   FLASH_FLAG_WRITE_1_1_2)
44111d7f826SLee Jones 	{ "w25x40",  0xef3013, 0,  64 * 1024,   8, W25X_FLAG, 75, NULL },
44211d7f826SLee Jones 	{ "w25x80",  0xef3014, 0,  64 * 1024,  16, W25X_FLAG, 75, NULL },
44311d7f826SLee Jones 	{ "w25x16",  0xef3015, 0,  64 * 1024,  32, W25X_FLAG, 75, NULL },
44411d7f826SLee Jones 	{ "w25x32",  0xef3016, 0,  64 * 1024,  64, W25X_FLAG, 75, NULL },
44511d7f826SLee Jones 	{ "w25x64",  0xef3017, 0,  64 * 1024, 128, W25X_FLAG, 75, NULL },
44611d7f826SLee Jones 
44711d7f826SLee Jones 	/* Winbond -- w25q "blocks" are 64K, "sectors" are 4KiB */
44811d7f826SLee Jones #define W25Q_FLAG (FLASH_FLAG_READ_WRITE       |	\
44911d7f826SLee Jones 		   FLASH_FLAG_READ_FAST         |	\
45011d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_2        |	\
45111d7f826SLee Jones 		   FLASH_FLAG_READ_1_2_2        |	\
45211d7f826SLee Jones 		   FLASH_FLAG_READ_1_1_4        |	\
45311d7f826SLee Jones 		   FLASH_FLAG_READ_1_4_4        |	\
45411d7f826SLee Jones 		   FLASH_FLAG_WRITE_1_1_4)
455cd7cac9eSLee Jones 	{ "w25q80",  0xef4014, 0,  64 * 1024,  16, W25Q_FLAG, 80,
456cd7cac9eSLee Jones 	  stfsm_w25q_config },
457cd7cac9eSLee Jones 	{ "w25q16",  0xef4015, 0,  64 * 1024,  32, W25Q_FLAG, 80,
458cd7cac9eSLee Jones 	  stfsm_w25q_config },
459cd7cac9eSLee Jones 	{ "w25q32",  0xef4016, 0,  64 * 1024,  64, W25Q_FLAG, 80,
460cd7cac9eSLee Jones 	  stfsm_w25q_config },
461cd7cac9eSLee Jones 	{ "w25q64",  0xef4017, 0,  64 * 1024, 128, W25Q_FLAG, 80,
462cd7cac9eSLee Jones 	  stfsm_w25q_config },
46311d7f826SLee Jones 
46411d7f826SLee Jones 	/* Sentinel */
46511d7f826SLee Jones 	{ NULL, 0x000000, 0, 0, 0, 0, 0, NULL },
46611d7f826SLee Jones };
46711d7f826SLee Jones 
468a37b2f5aSLee Jones /*
469a37b2f5aSLee Jones  * FSM message sequence configurations:
470a37b2f5aSLee Jones  *
471a37b2f5aSLee Jones  * All configs are presented in order of preference
472a37b2f5aSLee Jones  */
473a37b2f5aSLee Jones 
474a37b2f5aSLee Jones /* Default READ configurations, in order of preference */
475a37b2f5aSLee Jones static struct seq_rw_config default_read_configs[] = {
476a37b2f5aSLee Jones 	{FLASH_FLAG_READ_1_4_4, FLASH_CMD_READ_1_4_4,	0, 4, 4, 0x00, 2, 4},
477a37b2f5aSLee Jones 	{FLASH_FLAG_READ_1_1_4, FLASH_CMD_READ_1_1_4,	0, 1, 4, 0x00, 4, 0},
478a37b2f5aSLee Jones 	{FLASH_FLAG_READ_1_2_2, FLASH_CMD_READ_1_2_2,	0, 2, 2, 0x00, 4, 0},
479a37b2f5aSLee Jones 	{FLASH_FLAG_READ_1_1_2, FLASH_CMD_READ_1_1_2,	0, 1, 2, 0x00, 0, 8},
480a37b2f5aSLee Jones 	{FLASH_FLAG_READ_FAST,	FLASH_CMD_READ_FAST,	0, 1, 1, 0x00, 0, 8},
481a37b2f5aSLee Jones 	{FLASH_FLAG_READ_WRITE, FLASH_CMD_READ,		0, 1, 1, 0x00, 0, 0},
482a37b2f5aSLee Jones 	{0x00,			0,			0, 0, 0, 0x00, 0, 0},
483a37b2f5aSLee Jones };
484a37b2f5aSLee Jones 
485a37b2f5aSLee Jones /* Default WRITE configurations */
486a37b2f5aSLee Jones static struct seq_rw_config default_write_configs[] = {
487a37b2f5aSLee Jones 	{FLASH_FLAG_WRITE_1_4_4, FLASH_CMD_WRITE_1_4_4, 1, 4, 4, 0x00, 0, 0},
488a37b2f5aSLee Jones 	{FLASH_FLAG_WRITE_1_1_4, FLASH_CMD_WRITE_1_1_4, 1, 1, 4, 0x00, 0, 0},
489a37b2f5aSLee Jones 	{FLASH_FLAG_WRITE_1_2_2, FLASH_CMD_WRITE_1_2_2, 1, 2, 2, 0x00, 0, 0},
490a37b2f5aSLee Jones 	{FLASH_FLAG_WRITE_1_1_2, FLASH_CMD_WRITE_1_1_2, 1, 1, 2, 0x00, 0, 0},
491a37b2f5aSLee Jones 	{FLASH_FLAG_READ_WRITE,  FLASH_CMD_WRITE,       1, 1, 1, 0x00, 0, 0},
492a37b2f5aSLee Jones 	{0x00,			 0,			0, 0, 0, 0x00, 0, 0},
493a37b2f5aSLee Jones };
494a37b2f5aSLee Jones 
495e85a6196SLee Jones /*
496e85a6196SLee Jones  * [N25Qxxx] Configuration
497e85a6196SLee Jones  */
498e85a6196SLee Jones #define N25Q_VCR_DUMMY_CYCLES(x)	(((x) & 0xf) << 4)
499e85a6196SLee Jones #define N25Q_VCR_XIP_DISABLED		((uint8_t)0x1 << 3)
500e85a6196SLee Jones #define N25Q_VCR_WRAP_CONT		0x3
501e85a6196SLee Jones 
502e85a6196SLee Jones /* N25Q 3-byte Address READ configurations
503e85a6196SLee Jones  *	- 'FAST' variants configured for 8 dummy cycles.
504e85a6196SLee Jones  *
505e85a6196SLee Jones  * Note, the number of dummy cycles used for 'FAST' READ operations is
506e85a6196SLee Jones  * configurable and would normally be tuned according to the READ command and
507e85a6196SLee Jones  * operating frequency.  However, this applies universally to all 'FAST' READ
508e85a6196SLee Jones  * commands, including those used by the SPIBoot controller, and remains in
509e85a6196SLee Jones  * force until the device is power-cycled.  Since the SPIBoot controller is
510e85a6196SLee Jones  * hard-wired to use 8 dummy cycles, we must configure the device to also use 8
511e85a6196SLee Jones  * cycles.
512e85a6196SLee Jones  */
513e85a6196SLee Jones static struct seq_rw_config n25q_read3_configs[] = {
514e85a6196SLee Jones 	{FLASH_FLAG_READ_1_4_4, FLASH_CMD_READ_1_4_4,	0, 4, 4, 0x00, 0, 8},
515e85a6196SLee Jones 	{FLASH_FLAG_READ_1_1_4, FLASH_CMD_READ_1_1_4,	0, 1, 4, 0x00, 0, 8},
516e85a6196SLee Jones 	{FLASH_FLAG_READ_1_2_2, FLASH_CMD_READ_1_2_2,	0, 2, 2, 0x00, 0, 8},
517e85a6196SLee Jones 	{FLASH_FLAG_READ_1_1_2, FLASH_CMD_READ_1_1_2,	0, 1, 2, 0x00, 0, 8},
518e85a6196SLee Jones 	{FLASH_FLAG_READ_FAST,	FLASH_CMD_READ_FAST,	0, 1, 1, 0x00, 0, 8},
519e85a6196SLee Jones 	{FLASH_FLAG_READ_WRITE, FLASH_CMD_READ,	        0, 1, 1, 0x00, 0, 0},
520e85a6196SLee Jones 	{0x00,			0,			0, 0, 0, 0x00, 0, 0},
521e85a6196SLee Jones };
522e85a6196SLee Jones 
523e85a6196SLee Jones /* N25Q 4-byte Address READ configurations
524e85a6196SLee Jones  *	- use special 4-byte address READ commands (reduces overheads, and
525e85a6196SLee Jones  *        reduces risk of hitting watchdog reset issues).
526e85a6196SLee Jones  *	- 'FAST' variants configured for 8 dummy cycles (see note above.)
527e85a6196SLee Jones  */
528e85a6196SLee Jones static struct seq_rw_config n25q_read4_configs[] = {
529e85a6196SLee Jones 	{FLASH_FLAG_READ_1_4_4, FLASH_CMD_READ4_1_4_4,	0, 4, 4, 0x00, 0, 8},
530e85a6196SLee Jones 	{FLASH_FLAG_READ_1_1_4, FLASH_CMD_READ4_1_1_4,	0, 1, 4, 0x00, 0, 8},
531e85a6196SLee Jones 	{FLASH_FLAG_READ_1_2_2, FLASH_CMD_READ4_1_2_2,	0, 2, 2, 0x00, 0, 8},
532e85a6196SLee Jones 	{FLASH_FLAG_READ_1_1_2, FLASH_CMD_READ4_1_1_2,	0, 1, 2, 0x00, 0, 8},
533e85a6196SLee Jones 	{FLASH_FLAG_READ_FAST,	FLASH_CMD_READ4_FAST,	0, 1, 1, 0x00, 0, 8},
534e85a6196SLee Jones 	{FLASH_FLAG_READ_WRITE, FLASH_CMD_READ4,	0, 1, 1, 0x00, 0, 0},
535e85a6196SLee Jones 	{0x00,			0,			0, 0, 0, 0x00, 0, 0},
536e85a6196SLee Jones };
537e85a6196SLee Jones 
53889818066SLee Jones /*
53989818066SLee Jones  * [MX25xxx] Configuration
54089818066SLee Jones  */
54189818066SLee Jones #define MX25_STATUS_QE			(0x1 << 6)
54289818066SLee Jones 
54389818066SLee Jones static int stfsm_mx25_en_32bit_addr_seq(struct stfsm_seq *seq)
54489818066SLee Jones {
54589818066SLee Jones 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
54689818066SLee Jones 			   SEQ_OPC_CYCLES(8) |
54789818066SLee Jones 			   SEQ_OPC_OPCODE(FLASH_CMD_EN4B_ADDR) |
54889818066SLee Jones 			   SEQ_OPC_CSDEASSERT);
54989818066SLee Jones 
55089818066SLee Jones 	seq->seq[0] = STFSM_INST_CMD1;
55189818066SLee Jones 	seq->seq[1] = STFSM_INST_WAIT;
55289818066SLee Jones 	seq->seq[2] = STFSM_INST_STOP;
55389818066SLee Jones 
55489818066SLee Jones 	seq->seq_cfg = (SEQ_CFG_PADS_1 |
55589818066SLee Jones 			SEQ_CFG_ERASE |
55689818066SLee Jones 			SEQ_CFG_READNOTWRITE |
55789818066SLee Jones 			SEQ_CFG_CSDEASSERT |
55889818066SLee Jones 			SEQ_CFG_STARTSEQ);
55989818066SLee Jones 
56089818066SLee Jones 	return 0;
56189818066SLee Jones }
56289818066SLee Jones 
5635343a123SLee Jones /*
5645343a123SLee Jones  * [S25FLxxx] Configuration
5655343a123SLee Jones  */
5665343a123SLee Jones #define STFSM_S25FL_CONFIG_QE		(0x1 << 1)
5675343a123SLee Jones 
5685343a123SLee Jones /*
5695343a123SLee Jones  * S25FLxxxS devices provide three ways of supporting 32-bit addressing: Bank
5705343a123SLee Jones  * Register, Extended Address Modes, and a 32-bit address command set.  The
5715343a123SLee Jones  * 32-bit address command set is used here, since it avoids any problems with
5725343a123SLee Jones  * entering a state that is incompatible with the SPIBoot Controller.
5735343a123SLee Jones  */
5745343a123SLee Jones static struct seq_rw_config stfsm_s25fl_read4_configs[] = {
5755343a123SLee Jones 	{FLASH_FLAG_READ_1_4_4,  FLASH_CMD_READ4_1_4_4,  0, 4, 4, 0x00, 2, 4},
5765343a123SLee Jones 	{FLASH_FLAG_READ_1_1_4,  FLASH_CMD_READ4_1_1_4,  0, 1, 4, 0x00, 0, 8},
5775343a123SLee Jones 	{FLASH_FLAG_READ_1_2_2,  FLASH_CMD_READ4_1_2_2,  0, 2, 2, 0x00, 4, 0},
5785343a123SLee Jones 	{FLASH_FLAG_READ_1_1_2,  FLASH_CMD_READ4_1_1_2,  0, 1, 2, 0x00, 0, 8},
5795343a123SLee Jones 	{FLASH_FLAG_READ_FAST,   FLASH_CMD_READ4_FAST,   0, 1, 1, 0x00, 0, 8},
5805343a123SLee Jones 	{FLASH_FLAG_READ_WRITE,  FLASH_CMD_READ4,        0, 1, 1, 0x00, 0, 0},
5815343a123SLee Jones 	{0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
5825343a123SLee Jones };
5835343a123SLee Jones 
5845343a123SLee Jones static struct seq_rw_config stfsm_s25fl_write4_configs[] = {
5855343a123SLee Jones 	{FLASH_FLAG_WRITE_1_1_4, S25FL_CMD_WRITE4_1_1_4, 1, 1, 4, 0x00, 0, 0},
5865343a123SLee Jones 	{FLASH_FLAG_READ_WRITE,  S25FL_CMD_WRITE4,       1, 1, 1, 0x00, 0, 0},
5875343a123SLee Jones 	{0x00,                   0,                      0, 0, 0, 0x00, 0, 0},
5885343a123SLee Jones };
5895343a123SLee Jones 
590cd7cac9eSLee Jones /*
591cd7cac9eSLee Jones  * [W25Qxxx] Configuration
592cd7cac9eSLee Jones  */
593cd7cac9eSLee Jones #define W25Q_STATUS_QE			(0x1 << 9)
594cd7cac9eSLee Jones 
5951bd512b5SLee Jones static struct stfsm_seq stfsm_seq_read_jedec = {
5961bd512b5SLee Jones 	.data_size = TRANSFER_SIZE(8),
5971bd512b5SLee Jones 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
5981bd512b5SLee Jones 		       SEQ_OPC_CYCLES(8) |
5991bd512b5SLee Jones 		       SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
6001bd512b5SLee Jones 	.seq = {
6011bd512b5SLee Jones 		STFSM_INST_CMD1,
6021bd512b5SLee Jones 		STFSM_INST_DATA_READ,
6031bd512b5SLee Jones 		STFSM_INST_STOP,
6041bd512b5SLee Jones 	},
6051bd512b5SLee Jones 	.seq_cfg = (SEQ_CFG_PADS_1 |
6061bd512b5SLee Jones 		    SEQ_CFG_READNOTWRITE |
6071bd512b5SLee Jones 		    SEQ_CFG_CSDEASSERT |
6081bd512b5SLee Jones 		    SEQ_CFG_STARTSEQ),
6091bd512b5SLee Jones };
6101bd512b5SLee Jones 
611176b4377SLee Jones static struct stfsm_seq stfsm_seq_read_status_fifo = {
612176b4377SLee Jones 	.data_size = TRANSFER_SIZE(4),
613176b4377SLee Jones 	.seq_opc[0] = (SEQ_OPC_PADS_1 |
614176b4377SLee Jones 		       SEQ_OPC_CYCLES(8) |
615176b4377SLee Jones 		       SEQ_OPC_OPCODE(FLASH_CMD_RDSR)),
616176b4377SLee Jones 	.seq = {
617176b4377SLee Jones 		STFSM_INST_CMD1,
618176b4377SLee Jones 		STFSM_INST_DATA_READ,
619176b4377SLee Jones 		STFSM_INST_STOP,
620176b4377SLee Jones 	},
621176b4377SLee Jones 	.seq_cfg = (SEQ_CFG_PADS_1 |
622176b4377SLee Jones 		    SEQ_CFG_READNOTWRITE |
623176b4377SLee Jones 		    SEQ_CFG_CSDEASSERT |
624176b4377SLee Jones 		    SEQ_CFG_STARTSEQ),
625176b4377SLee Jones };
626176b4377SLee Jones 
627fa5ba3afSLee Jones static struct stfsm_seq stfsm_seq_erase_sector = {
628fa5ba3afSLee Jones 	/* 'addr_cfg' configured during initialisation */
629fa5ba3afSLee Jones 	.seq_opc = {
630fa5ba3afSLee Jones 		(SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
631fa5ba3afSLee Jones 		 SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
632fa5ba3afSLee Jones 
633fa5ba3afSLee Jones 		(SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
634fa5ba3afSLee Jones 		 SEQ_OPC_OPCODE(FLASH_CMD_SE)),
635fa5ba3afSLee Jones 	},
636fa5ba3afSLee Jones 	.seq = {
637fa5ba3afSLee Jones 		STFSM_INST_CMD1,
638fa5ba3afSLee Jones 		STFSM_INST_CMD2,
639fa5ba3afSLee Jones 		STFSM_INST_ADD1,
640fa5ba3afSLee Jones 		STFSM_INST_ADD2,
641fa5ba3afSLee Jones 		STFSM_INST_STOP,
642fa5ba3afSLee Jones 	},
643fa5ba3afSLee Jones 	.seq_cfg = (SEQ_CFG_PADS_1 |
644fa5ba3afSLee Jones 		    SEQ_CFG_READNOTWRITE |
645fa5ba3afSLee Jones 		    SEQ_CFG_CSDEASSERT |
646fa5ba3afSLee Jones 		    SEQ_CFG_STARTSEQ),
647fa5ba3afSLee Jones };
648fa5ba3afSLee Jones 
6494a341fe7SLee Jones static struct stfsm_seq stfsm_seq_erase_chip = {
6504a341fe7SLee Jones 	.seq_opc = {
6514a341fe7SLee Jones 		(SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
6524a341fe7SLee Jones 		 SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
6534a341fe7SLee Jones 
6544a341fe7SLee Jones 		(SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
6554a341fe7SLee Jones 		 SEQ_OPC_OPCODE(FLASH_CMD_CHIPERASE) | SEQ_OPC_CSDEASSERT),
6564a341fe7SLee Jones 	},
6574a341fe7SLee Jones 	.seq = {
6584a341fe7SLee Jones 		STFSM_INST_CMD1,
6594a341fe7SLee Jones 		STFSM_INST_CMD2,
6604a341fe7SLee Jones 		STFSM_INST_WAIT,
6614a341fe7SLee Jones 		STFSM_INST_STOP,
6624a341fe7SLee Jones 	},
6634a341fe7SLee Jones 	.seq_cfg = (SEQ_CFG_PADS_1 |
6644a341fe7SLee Jones 		    SEQ_CFG_ERASE |
6654a341fe7SLee Jones 		    SEQ_CFG_READNOTWRITE |
6664a341fe7SLee Jones 		    SEQ_CFG_CSDEASSERT |
6674a341fe7SLee Jones 		    SEQ_CFG_STARTSEQ),
6684a341fe7SLee Jones };
6694a341fe7SLee Jones 
670150571b7SLee Jones static struct stfsm_seq stfsm_seq_write_status = {
671150571b7SLee Jones 	.seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
672150571b7SLee Jones 		       SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
673150571b7SLee Jones 	.seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
674150571b7SLee Jones 		       SEQ_OPC_OPCODE(FLASH_CMD_WRSR)),
675150571b7SLee Jones 	.seq = {
676150571b7SLee Jones 		STFSM_INST_CMD1,
677150571b7SLee Jones 		STFSM_INST_CMD2,
678150571b7SLee Jones 		STFSM_INST_STA_WR1,
679150571b7SLee Jones 		STFSM_INST_STOP,
680150571b7SLee Jones 	},
681150571b7SLee Jones 	.seq_cfg = (SEQ_CFG_PADS_1 |
682150571b7SLee Jones 		    SEQ_CFG_READNOTWRITE |
683150571b7SLee Jones 		    SEQ_CFG_CSDEASSERT |
684150571b7SLee Jones 		    SEQ_CFG_STARTSEQ),
685150571b7SLee Jones };
686150571b7SLee Jones 
687249516c9SLee Jones static struct stfsm_seq stfsm_seq_wrvcr = {
688249516c9SLee Jones 	.seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
689249516c9SLee Jones 		       SEQ_OPC_OPCODE(FLASH_CMD_WREN) | SEQ_OPC_CSDEASSERT),
690249516c9SLee Jones 	.seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
691249516c9SLee Jones 		       SEQ_OPC_OPCODE(FLASH_CMD_WRVCR)),
692249516c9SLee Jones 	.seq = {
693249516c9SLee Jones 		STFSM_INST_CMD1,
694249516c9SLee Jones 		STFSM_INST_CMD2,
695249516c9SLee Jones 		STFSM_INST_STA_WR1,
696249516c9SLee Jones 		STFSM_INST_STOP,
697249516c9SLee Jones 	},
698249516c9SLee Jones 	.seq_cfg = (SEQ_CFG_PADS_1 |
699249516c9SLee Jones 		    SEQ_CFG_READNOTWRITE |
700249516c9SLee Jones 		    SEQ_CFG_CSDEASSERT |
701249516c9SLee Jones 		    SEQ_CFG_STARTSEQ),
702249516c9SLee Jones };
703249516c9SLee Jones 
7046bd29600SLee Jones static int stfsm_n25q_en_32bit_addr_seq(struct stfsm_seq *seq)
7056bd29600SLee Jones {
7066bd29600SLee Jones 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
7076bd29600SLee Jones 			   SEQ_OPC_OPCODE(FLASH_CMD_EN4B_ADDR));
7086bd29600SLee Jones 	seq->seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
7096bd29600SLee Jones 			   SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
7106bd29600SLee Jones 			   SEQ_OPC_CSDEASSERT);
7116bd29600SLee Jones 
7126bd29600SLee Jones 	seq->seq[0] = STFSM_INST_CMD2;
7136bd29600SLee Jones 	seq->seq[1] = STFSM_INST_CMD1;
7146bd29600SLee Jones 	seq->seq[2] = STFSM_INST_WAIT;
7156bd29600SLee Jones 	seq->seq[3] = STFSM_INST_STOP;
7166bd29600SLee Jones 
7176bd29600SLee Jones 	seq->seq_cfg = (SEQ_CFG_PADS_1 |
7186bd29600SLee Jones 			SEQ_CFG_ERASE |
7196bd29600SLee Jones 			SEQ_CFG_READNOTWRITE |
7206bd29600SLee Jones 			SEQ_CFG_CSDEASSERT |
7216bd29600SLee Jones 			SEQ_CFG_STARTSEQ);
7226bd29600SLee Jones 
7236bd29600SLee Jones 	return 0;
7246bd29600SLee Jones }
7256bd29600SLee Jones 
7263c8b85b3SLee Jones static inline int stfsm_is_idle(struct stfsm *fsm)
7273c8b85b3SLee Jones {
7283c8b85b3SLee Jones 	return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
7293c8b85b3SLee Jones }
7303c8b85b3SLee Jones 
73186f309fdSLee Jones static inline uint32_t stfsm_fifo_available(struct stfsm *fsm)
73286f309fdSLee Jones {
73386f309fdSLee Jones 	return (readl(fsm->base + SPI_FAST_SEQ_STA) >> 5) & 0x7f;
73486f309fdSLee Jones }
73586f309fdSLee Jones 
73686f309fdSLee Jones static void stfsm_clear_fifo(struct stfsm *fsm)
73786f309fdSLee Jones {
73886f309fdSLee Jones 	uint32_t avail;
73986f309fdSLee Jones 
74086f309fdSLee Jones 	for (;;) {
74186f309fdSLee Jones 		avail = stfsm_fifo_available(fsm);
74286f309fdSLee Jones 		if (!avail)
74386f309fdSLee Jones 			break;
74486f309fdSLee Jones 
74586f309fdSLee Jones 		while (avail) {
74686f309fdSLee Jones 			readl(fsm->base + SPI_FAST_SEQ_DATA_REG);
74786f309fdSLee Jones 			avail--;
74886f309fdSLee Jones 		}
74986f309fdSLee Jones 	}
75086f309fdSLee Jones }
75186f309fdSLee Jones 
7523c8b85b3SLee Jones static inline void stfsm_load_seq(struct stfsm *fsm,
7533c8b85b3SLee Jones 				  const struct stfsm_seq *seq)
7543c8b85b3SLee Jones {
7553c8b85b3SLee Jones 	void __iomem *dst = fsm->base + SPI_FAST_SEQ_TRANSFER_SIZE;
7563c8b85b3SLee Jones 	const uint32_t *src = (const uint32_t *)seq;
7573c8b85b3SLee Jones 	int words = sizeof(*seq) / sizeof(*src);
7583c8b85b3SLee Jones 
7593c8b85b3SLee Jones 	BUG_ON(!stfsm_is_idle(fsm));
7603c8b85b3SLee Jones 
7613c8b85b3SLee Jones 	while (words--) {
7623c8b85b3SLee Jones 		writel(*src, dst);
7633c8b85b3SLee Jones 		src++;
7643c8b85b3SLee Jones 		dst += 4;
7653c8b85b3SLee Jones 	}
7663c8b85b3SLee Jones }
7673c8b85b3SLee Jones 
7683c8b85b3SLee Jones static void stfsm_wait_seq(struct stfsm *fsm)
7693c8b85b3SLee Jones {
7703c8b85b3SLee Jones 	unsigned long deadline;
7713c8b85b3SLee Jones 	int timeout = 0;
7723c8b85b3SLee Jones 
7733c8b85b3SLee Jones 	deadline = jiffies + msecs_to_jiffies(STFSM_MAX_WAIT_SEQ_MS);
7743c8b85b3SLee Jones 
7753c8b85b3SLee Jones 	while (!timeout) {
7763c8b85b3SLee Jones 		if (time_after_eq(jiffies, deadline))
7773c8b85b3SLee Jones 			timeout = 1;
7783c8b85b3SLee Jones 
7793c8b85b3SLee Jones 		if (stfsm_is_idle(fsm))
7803c8b85b3SLee Jones 			return;
7813c8b85b3SLee Jones 
7823c8b85b3SLee Jones 		cond_resched();
7833c8b85b3SLee Jones 	}
7843c8b85b3SLee Jones 
7853c8b85b3SLee Jones 	dev_err(fsm->dev, "timeout on sequence completion\n");
7863c8b85b3SLee Jones }
7873c8b85b3SLee Jones 
788030e82dcSLee Jones static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf,
789030e82dcSLee Jones 			    const uint32_t size)
790030e82dcSLee Jones {
791030e82dcSLee Jones 	uint32_t remaining = size >> 2;
792030e82dcSLee Jones 	uint32_t avail;
793030e82dcSLee Jones 	uint32_t words;
794030e82dcSLee Jones 
795030e82dcSLee Jones 	dev_dbg(fsm->dev, "Reading %d bytes from FIFO\n", size);
796030e82dcSLee Jones 
797030e82dcSLee Jones 	BUG_ON((((uint32_t)buf) & 0x3) || (size & 0x3));
798030e82dcSLee Jones 
799030e82dcSLee Jones 	while (remaining) {
800030e82dcSLee Jones 		for (;;) {
801030e82dcSLee Jones 			avail = stfsm_fifo_available(fsm);
802030e82dcSLee Jones 			if (avail)
803030e82dcSLee Jones 				break;
804030e82dcSLee Jones 			udelay(1);
805030e82dcSLee Jones 		}
806030e82dcSLee Jones 		words = min(avail, remaining);
807030e82dcSLee Jones 		remaining -= words;
808030e82dcSLee Jones 
809030e82dcSLee Jones 		readsl(fsm->base + SPI_FAST_SEQ_DATA_REG, buf, words);
810030e82dcSLee Jones 		buf += words;
811030e82dcSLee Jones 	}
812030e82dcSLee Jones }
813030e82dcSLee Jones 
81430ca64f9SLee Jones static int stfsm_write_fifo(struct stfsm *fsm,
81530ca64f9SLee Jones 			    const uint32_t *buf, const uint32_t size)
81630ca64f9SLee Jones {
81730ca64f9SLee Jones 	uint32_t words = size >> 2;
81830ca64f9SLee Jones 
81930ca64f9SLee Jones 	dev_dbg(fsm->dev, "writing %d bytes to FIFO\n", size);
82030ca64f9SLee Jones 
82130ca64f9SLee Jones 	BUG_ON((((uint32_t)buf) & 0x3) || (size & 0x3));
82230ca64f9SLee Jones 
82330ca64f9SLee Jones 	writesl(fsm->base + SPI_FAST_SEQ_DATA_REG, buf, words);
82430ca64f9SLee Jones 
82530ca64f9SLee Jones 	return size;
82630ca64f9SLee Jones }
82730ca64f9SLee Jones 
8280de08e43SLee Jones static int stfsm_enter_32bit_addr(struct stfsm *fsm, int enter)
8290de08e43SLee Jones {
830e6b1bb4eSLee Jones 	struct stfsm_seq *seq = &fsm->stfsm_seq_en_32bit_addr;
8310de08e43SLee Jones 	uint32_t cmd = enter ? FLASH_CMD_EN4B_ADDR : FLASH_CMD_EX4B_ADDR;
8320de08e43SLee Jones 
8330de08e43SLee Jones 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
8340de08e43SLee Jones 			   SEQ_OPC_CYCLES(8) |
8350de08e43SLee Jones 			   SEQ_OPC_OPCODE(cmd) |
8360de08e43SLee Jones 			   SEQ_OPC_CSDEASSERT);
8370de08e43SLee Jones 
8380de08e43SLee Jones 	stfsm_load_seq(fsm, seq);
8390de08e43SLee Jones 
8400de08e43SLee Jones 	stfsm_wait_seq(fsm);
8410de08e43SLee Jones 
8420de08e43SLee Jones 	return 0;
8430de08e43SLee Jones }
8440de08e43SLee Jones 
845176b4377SLee Jones static uint8_t stfsm_wait_busy(struct stfsm *fsm)
846176b4377SLee Jones {
847176b4377SLee Jones 	struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
848176b4377SLee Jones 	unsigned long deadline;
849176b4377SLee Jones 	uint32_t status;
850176b4377SLee Jones 	int timeout = 0;
851176b4377SLee Jones 
852176b4377SLee Jones 	/* Use RDRS1 */
853176b4377SLee Jones 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
854176b4377SLee Jones 			   SEQ_OPC_CYCLES(8) |
855176b4377SLee Jones 			   SEQ_OPC_OPCODE(FLASH_CMD_RDSR));
856176b4377SLee Jones 
857176b4377SLee Jones 	/* Load read_status sequence */
858176b4377SLee Jones 	stfsm_load_seq(fsm, seq);
859176b4377SLee Jones 
860176b4377SLee Jones 	/*
861176b4377SLee Jones 	 * Repeat until busy bit is deasserted, or timeout, or error (S25FLxxxS)
862176b4377SLee Jones 	 */
863176b4377SLee Jones 	deadline = jiffies + FLASH_MAX_BUSY_WAIT;
864176b4377SLee Jones 	while (!timeout) {
865176b4377SLee Jones 		cond_resched();
866176b4377SLee Jones 
867176b4377SLee Jones 		if (time_after_eq(jiffies, deadline))
868176b4377SLee Jones 			timeout = 1;
869176b4377SLee Jones 
870176b4377SLee Jones 		stfsm_wait_seq(fsm);
871176b4377SLee Jones 
872176b4377SLee Jones 		stfsm_read_fifo(fsm, &status, 4);
873176b4377SLee Jones 
874176b4377SLee Jones 		if ((status & FLASH_STATUS_BUSY) == 0)
875176b4377SLee Jones 			return 0;
876176b4377SLee Jones 
877176b4377SLee Jones 		if ((fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS) &&
878176b4377SLee Jones 		    ((status & S25FL_STATUS_P_ERR) ||
879176b4377SLee Jones 		     (status & S25FL_STATUS_E_ERR)))
880176b4377SLee Jones 			return (uint8_t)(status & 0xff);
881176b4377SLee Jones 
882176b4377SLee Jones 		if (!timeout)
883176b4377SLee Jones 			/* Restart */
884176b4377SLee Jones 			writel(seq->seq_cfg, fsm->base + SPI_FAST_SEQ_CFG);
885176b4377SLee Jones 	}
886176b4377SLee Jones 
887176b4377SLee Jones 	dev_err(fsm->dev, "timeout on wait_busy\n");
888176b4377SLee Jones 
889176b4377SLee Jones 	return FLASH_STATUS_TIMEOUT;
890176b4377SLee Jones }
891176b4377SLee Jones 
892ac94dbcbSLee Jones static int stfsm_read_status(struct stfsm *fsm, uint8_t cmd,
893ac94dbcbSLee Jones 			   uint8_t *status)
894ac94dbcbSLee Jones {
895ac94dbcbSLee Jones 	struct stfsm_seq *seq = &stfsm_seq_read_status_fifo;
896ac94dbcbSLee Jones 	uint32_t tmp;
897ac94dbcbSLee Jones 
898ac94dbcbSLee Jones 	dev_dbg(fsm->dev, "reading STA[%s]\n",
899ac94dbcbSLee Jones 		(cmd == FLASH_CMD_RDSR) ? "1" : "2");
900ac94dbcbSLee Jones 
901ac94dbcbSLee Jones 	seq->seq_opc[0] = (SEQ_OPC_PADS_1 |
902ac94dbcbSLee Jones 			   SEQ_OPC_CYCLES(8) |
903ac94dbcbSLee Jones 			   SEQ_OPC_OPCODE(cmd)),
904ac94dbcbSLee Jones 
905ac94dbcbSLee Jones 	stfsm_load_seq(fsm, seq);
906ac94dbcbSLee Jones 
907ac94dbcbSLee Jones 	stfsm_read_fifo(fsm, &tmp, 4);
908ac94dbcbSLee Jones 
909ac94dbcbSLee Jones 	*status = (uint8_t)(tmp >> 24);
910ac94dbcbSLee Jones 
911ac94dbcbSLee Jones 	stfsm_wait_seq(fsm);
912ac94dbcbSLee Jones 
913ac94dbcbSLee Jones 	return 0;
914ac94dbcbSLee Jones }
915ac94dbcbSLee Jones 
916150571b7SLee Jones static int stfsm_write_status(struct stfsm *fsm, uint16_t status,
917150571b7SLee Jones 			       int sta_bytes)
918150571b7SLee Jones {
919150571b7SLee Jones 	struct stfsm_seq *seq = &stfsm_seq_write_status;
920150571b7SLee Jones 
921150571b7SLee Jones 	dev_dbg(fsm->dev, "writing STA[%s] 0x%04x\n",
922150571b7SLee Jones 		(sta_bytes == 1) ? "1" : "1+2", status);
923150571b7SLee Jones 
924150571b7SLee Jones 	seq->status = (uint32_t)status | STA_PADS_1 | STA_CSDEASSERT;
925150571b7SLee Jones 	seq->seq[2] = (sta_bytes == 1) ?
926150571b7SLee Jones 		STFSM_INST_STA_WR1 : STFSM_INST_STA_WR1_2;
927150571b7SLee Jones 
928150571b7SLee Jones 	stfsm_load_seq(fsm, seq);
929150571b7SLee Jones 
930150571b7SLee Jones 	stfsm_wait_seq(fsm);
931150571b7SLee Jones 
932150571b7SLee Jones 	return 0;
933150571b7SLee Jones };
934150571b7SLee Jones 
935249516c9SLee Jones static int stfsm_wrvcr(struct stfsm *fsm, uint8_t data)
936249516c9SLee Jones {
937249516c9SLee Jones 	struct stfsm_seq *seq = &stfsm_seq_wrvcr;
938249516c9SLee Jones 
939249516c9SLee Jones 	dev_dbg(fsm->dev, "writing VCR 0x%02x\n", data);
940249516c9SLee Jones 
941249516c9SLee Jones 	seq->status = (STA_DATA_BYTE1(data) | STA_PADS_1 | STA_CSDEASSERT);
942249516c9SLee Jones 
943249516c9SLee Jones 	stfsm_load_seq(fsm, seq);
944249516c9SLee Jones 
945249516c9SLee Jones 	stfsm_wait_seq(fsm);
946249516c9SLee Jones 
947249516c9SLee Jones 	return 0;
948249516c9SLee Jones }
949249516c9SLee Jones 
9500ea7d706SLee Jones /*
9510ea7d706SLee Jones  * SoC reset on 'boot-from-spi' systems
9520ea7d706SLee Jones  *
9530ea7d706SLee Jones  * Certain modes of operation cause the Flash device to enter a particular state
9540ea7d706SLee Jones  * for a period of time (e.g. 'Erase Sector', 'Quad Enable', and 'Enter 32-bit
9550ea7d706SLee Jones  * Addr' commands).  On boot-from-spi systems, it is important to consider what
9560ea7d706SLee Jones  * happens if a warm reset occurs during this period.  The SPIBoot controller
9570ea7d706SLee Jones  * assumes that Flash device is in its default reset state, 24-bit address mode,
9580ea7d706SLee Jones  * and ready to accept commands.  This can be achieved using some form of
9590ea7d706SLee Jones  * on-board logic/controller to force a device POR in response to a SoC-level
9600ea7d706SLee Jones  * reset or by making use of the device reset signal if available (limited
9610ea7d706SLee Jones  * number of devices only).
9620ea7d706SLee Jones  *
9630ea7d706SLee Jones  * Failure to take such precautions can cause problems following a warm reset.
9640ea7d706SLee Jones  * For some operations (e.g. ERASE), there is little that can be done.  For
9650ea7d706SLee Jones  * other modes of operation (e.g. 32-bit addressing), options are often
9660ea7d706SLee Jones  * available that can help minimise the window in which a reset could cause a
9670ea7d706SLee Jones  * problem.
9680ea7d706SLee Jones  *
9690ea7d706SLee Jones  */
9700ea7d706SLee Jones static bool stfsm_can_handle_soc_reset(struct stfsm *fsm)
9710ea7d706SLee Jones {
9720ea7d706SLee Jones 	/* Reset signal is available on the board and supported by the device */
9730ea7d706SLee Jones 	if (fsm->reset_signal && fsm->info->flags & FLASH_FLAG_RESET)
9740ea7d706SLee Jones 		return true;
9750ea7d706SLee Jones 
9760ea7d706SLee Jones 	/* Board-level logic forces a power-on-reset */
9770ea7d706SLee Jones 	if (fsm->reset_por)
9780ea7d706SLee Jones 		return true;
9790ea7d706SLee Jones 
9800ea7d706SLee Jones 	/* Reset is not properly handled and may result in failure to reboot */
9810ea7d706SLee Jones 	return false;
9820ea7d706SLee Jones }
9830ea7d706SLee Jones 
984fa5ba3afSLee Jones /* Configure 'addr_cfg' according to addressing mode */
985fa5ba3afSLee Jones static void stfsm_prepare_erasesec_seq(struct stfsm *fsm,
986fa5ba3afSLee Jones 				       struct stfsm_seq *seq)
987fa5ba3afSLee Jones {
988fa5ba3afSLee Jones 	int addr1_cycles = fsm->info->flags & FLASH_FLAG_32BIT_ADDR ? 16 : 8;
989fa5ba3afSLee Jones 
990fa5ba3afSLee Jones 	seq->addr_cfg = (ADR_CFG_CYCLES_ADD1(addr1_cycles) |
991fa5ba3afSLee Jones 			 ADR_CFG_PADS_1_ADD1 |
992fa5ba3afSLee Jones 			 ADR_CFG_CYCLES_ADD2(16) |
993fa5ba3afSLee Jones 			 ADR_CFG_PADS_1_ADD2 |
994fa5ba3afSLee Jones 			 ADR_CFG_CSDEASSERT_ADD2);
995fa5ba3afSLee Jones }
996fa5ba3afSLee Jones 
99708981274SLee Jones /* Search for preferred configuration based on available flags */
99808981274SLee Jones static struct seq_rw_config *
99908981274SLee Jones stfsm_search_seq_rw_configs(struct stfsm *fsm,
100008981274SLee Jones 			    struct seq_rw_config cfgs[])
100108981274SLee Jones {
100208981274SLee Jones 	struct seq_rw_config *config;
100308981274SLee Jones 	int flags = fsm->info->flags;
100408981274SLee Jones 
100508981274SLee Jones 	for (config = cfgs; config->cmd != 0; config++)
100608981274SLee Jones 		if ((config->flags & flags) == config->flags)
100708981274SLee Jones 			return config;
100808981274SLee Jones 
100908981274SLee Jones 	return NULL;
101008981274SLee Jones }
101108981274SLee Jones 
101297ccf2d2SLee Jones /* Prepare a READ/WRITE sequence according to configuration parameters */
101397ccf2d2SLee Jones static void stfsm_prepare_rw_seq(struct stfsm *fsm,
101497ccf2d2SLee Jones 				 struct stfsm_seq *seq,
101597ccf2d2SLee Jones 				 struct seq_rw_config *cfg)
101697ccf2d2SLee Jones {
101797ccf2d2SLee Jones 	int addr1_cycles, addr2_cycles;
101897ccf2d2SLee Jones 	int i = 0;
101997ccf2d2SLee Jones 
102097ccf2d2SLee Jones 	memset(seq, 0, sizeof(*seq));
102197ccf2d2SLee Jones 
102297ccf2d2SLee Jones 	/* Add READ/WRITE OPC  */
102397ccf2d2SLee Jones 	seq->seq_opc[i++] = (SEQ_OPC_PADS_1 |
102497ccf2d2SLee Jones 			     SEQ_OPC_CYCLES(8) |
102597ccf2d2SLee Jones 			     SEQ_OPC_OPCODE(cfg->cmd));
102697ccf2d2SLee Jones 
102797ccf2d2SLee Jones 	/* Add WREN OPC for a WRITE sequence */
102897ccf2d2SLee Jones 	if (cfg->write)
102997ccf2d2SLee Jones 		seq->seq_opc[i++] = (SEQ_OPC_PADS_1 |
103097ccf2d2SLee Jones 				     SEQ_OPC_CYCLES(8) |
103197ccf2d2SLee Jones 				     SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
103297ccf2d2SLee Jones 				     SEQ_OPC_CSDEASSERT);
103397ccf2d2SLee Jones 
103497ccf2d2SLee Jones 	/* Address configuration (24 or 32-bit addresses) */
103597ccf2d2SLee Jones 	addr1_cycles  = (fsm->info->flags & FLASH_FLAG_32BIT_ADDR) ? 16 : 8;
103697ccf2d2SLee Jones 	addr1_cycles /= cfg->addr_pads;
103797ccf2d2SLee Jones 	addr2_cycles  = 16 / cfg->addr_pads;
103897ccf2d2SLee Jones 	seq->addr_cfg = ((addr1_cycles & 0x3f) << 0 |	/* ADD1 cycles */
103997ccf2d2SLee Jones 			 (cfg->addr_pads - 1) << 6 |	/* ADD1 pads */
104097ccf2d2SLee Jones 			 (addr2_cycles & 0x3f) << 16 |	/* ADD2 cycles */
104197ccf2d2SLee Jones 			 ((cfg->addr_pads - 1) << 22));	/* ADD2 pads */
104297ccf2d2SLee Jones 
104397ccf2d2SLee Jones 	/* Data/Sequence configuration */
104497ccf2d2SLee Jones 	seq->seq_cfg = ((cfg->data_pads - 1) << 16 |
104597ccf2d2SLee Jones 			SEQ_CFG_STARTSEQ |
104697ccf2d2SLee Jones 			SEQ_CFG_CSDEASSERT);
104797ccf2d2SLee Jones 	if (!cfg->write)
104897ccf2d2SLee Jones 		seq->seq_cfg |= SEQ_CFG_READNOTWRITE;
104997ccf2d2SLee Jones 
105097ccf2d2SLee Jones 	/* Mode configuration (no. of pads taken from addr cfg) */
105197ccf2d2SLee Jones 	seq->mode = ((cfg->mode_data & 0xff) << 0 |	/* data */
105297ccf2d2SLee Jones 		     (cfg->mode_cycles & 0x3f) << 16 |	/* cycles */
105397ccf2d2SLee Jones 		     (cfg->addr_pads - 1) << 22);	/* pads */
105497ccf2d2SLee Jones 
105597ccf2d2SLee Jones 	/* Dummy configuration (no. of pads taken from addr cfg) */
105697ccf2d2SLee Jones 	seq->dummy = ((cfg->dummy_cycles & 0x3f) << 16 |	/* cycles */
105797ccf2d2SLee Jones 		      (cfg->addr_pads - 1) << 22);		/* pads */
105897ccf2d2SLee Jones 
105997ccf2d2SLee Jones 
106097ccf2d2SLee Jones 	/* Instruction sequence */
106197ccf2d2SLee Jones 	i = 0;
106297ccf2d2SLee Jones 	if (cfg->write)
106397ccf2d2SLee Jones 		seq->seq[i++] = STFSM_INST_CMD2;
106497ccf2d2SLee Jones 
106597ccf2d2SLee Jones 	seq->seq[i++] = STFSM_INST_CMD1;
106697ccf2d2SLee Jones 
106797ccf2d2SLee Jones 	seq->seq[i++] = STFSM_INST_ADD1;
106897ccf2d2SLee Jones 	seq->seq[i++] = STFSM_INST_ADD2;
106997ccf2d2SLee Jones 
107097ccf2d2SLee Jones 	if (cfg->mode_cycles)
107197ccf2d2SLee Jones 		seq->seq[i++] = STFSM_INST_MODE;
107297ccf2d2SLee Jones 
107397ccf2d2SLee Jones 	if (cfg->dummy_cycles)
107497ccf2d2SLee Jones 		seq->seq[i++] = STFSM_INST_DUMMY;
107597ccf2d2SLee Jones 
107697ccf2d2SLee Jones 	seq->seq[i++] =
107797ccf2d2SLee Jones 		cfg->write ? STFSM_INST_DATA_WRITE : STFSM_INST_DATA_READ;
107897ccf2d2SLee Jones 	seq->seq[i++] = STFSM_INST_STOP;
107997ccf2d2SLee Jones }
108097ccf2d2SLee Jones 
108188cccb89SLee Jones static int stfsm_search_prepare_rw_seq(struct stfsm *fsm,
108288cccb89SLee Jones 				       struct stfsm_seq *seq,
108388cccb89SLee Jones 				       struct seq_rw_config *cfgs)
108488cccb89SLee Jones {
108588cccb89SLee Jones 	struct seq_rw_config *config;
108688cccb89SLee Jones 
108788cccb89SLee Jones 	config = stfsm_search_seq_rw_configs(fsm, cfgs);
108888cccb89SLee Jones 	if (!config) {
108988cccb89SLee Jones 		dev_err(fsm->dev, "failed to find suitable config\n");
109088cccb89SLee Jones 		return -EINVAL;
109188cccb89SLee Jones 	}
109288cccb89SLee Jones 
109388cccb89SLee Jones 	stfsm_prepare_rw_seq(fsm, seq, config);
109488cccb89SLee Jones 
109588cccb89SLee Jones 	return 0;
109688cccb89SLee Jones }
109788cccb89SLee Jones 
10984eb3f0d8SLee Jones /* Prepare a READ/WRITE/ERASE 'default' sequences */
10994eb3f0d8SLee Jones static int stfsm_prepare_rwe_seqs_default(struct stfsm *fsm)
11004eb3f0d8SLee Jones {
11014eb3f0d8SLee Jones 	uint32_t flags = fsm->info->flags;
11024eb3f0d8SLee Jones 	int ret;
11034eb3f0d8SLee Jones 
11044eb3f0d8SLee Jones 	/* Configure 'READ' sequence */
1105e6b1bb4eSLee Jones 	ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
11064eb3f0d8SLee Jones 					  default_read_configs);
11074eb3f0d8SLee Jones 	if (ret) {
11084eb3f0d8SLee Jones 		dev_err(fsm->dev,
11094eb3f0d8SLee Jones 			"failed to prep READ sequence with flags [0x%08x]\n",
11104eb3f0d8SLee Jones 			flags);
11114eb3f0d8SLee Jones 		return ret;
11124eb3f0d8SLee Jones 	}
11134eb3f0d8SLee Jones 
11144eb3f0d8SLee Jones 	/* Configure 'WRITE' sequence */
1115e6b1bb4eSLee Jones 	ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
11164eb3f0d8SLee Jones 					  default_write_configs);
11174eb3f0d8SLee Jones 	if (ret) {
11184eb3f0d8SLee Jones 		dev_err(fsm->dev,
11194eb3f0d8SLee Jones 			"failed to prep WRITE sequence with flags [0x%08x]\n",
11204eb3f0d8SLee Jones 			flags);
11214eb3f0d8SLee Jones 		return ret;
11224eb3f0d8SLee Jones 	}
11234eb3f0d8SLee Jones 
11244eb3f0d8SLee Jones 	/* Configure 'ERASE_SECTOR' sequence */
11254eb3f0d8SLee Jones 	stfsm_prepare_erasesec_seq(fsm, &stfsm_seq_erase_sector);
11264eb3f0d8SLee Jones 
11274eb3f0d8SLee Jones 	return 0;
11284eb3f0d8SLee Jones }
11294eb3f0d8SLee Jones 
113089818066SLee Jones static int stfsm_mx25_config(struct stfsm *fsm)
113189818066SLee Jones {
113289818066SLee Jones 	uint32_t flags = fsm->info->flags;
113389818066SLee Jones 	uint32_t data_pads;
113489818066SLee Jones 	uint8_t sta;
113589818066SLee Jones 	int ret;
113689818066SLee Jones 	bool soc_reset;
113789818066SLee Jones 
113889818066SLee Jones 	/*
113989818066SLee Jones 	 * Use default READ/WRITE sequences
114089818066SLee Jones 	 */
114189818066SLee Jones 	ret = stfsm_prepare_rwe_seqs_default(fsm);
114289818066SLee Jones 	if (ret)
114389818066SLee Jones 		return ret;
114489818066SLee Jones 
114589818066SLee Jones 	/*
114689818066SLee Jones 	 * Configure 32-bit Address Support
114789818066SLee Jones 	 */
114889818066SLee Jones 	if (flags & FLASH_FLAG_32BIT_ADDR) {
114989818066SLee Jones 		/* Configure 'enter_32bitaddr' FSM sequence */
1150e6b1bb4eSLee Jones 		stfsm_mx25_en_32bit_addr_seq(&fsm->stfsm_seq_en_32bit_addr);
115189818066SLee Jones 
115289818066SLee Jones 		soc_reset = stfsm_can_handle_soc_reset(fsm);
115389818066SLee Jones 		if (soc_reset || !fsm->booted_from_spi) {
115489818066SLee Jones 			/* If we can handle SoC resets, we enable 32-bit address
115589818066SLee Jones 			 * mode pervasively */
115689818066SLee Jones 			stfsm_enter_32bit_addr(fsm, 1);
115789818066SLee Jones 
115889818066SLee Jones 		} else {
115989818066SLee Jones 			/* Else, enable/disable 32-bit addressing before/after
116089818066SLee Jones 			 * each operation */
116189818066SLee Jones 			fsm->configuration = (CFG_READ_TOGGLE_32BIT_ADDR |
116289818066SLee Jones 					      CFG_WRITE_TOGGLE_32BIT_ADDR |
116389818066SLee Jones 					      CFG_ERASESEC_TOGGLE_32BIT_ADDR);
116489818066SLee Jones 			/* It seems a small delay is required after exiting
116589818066SLee Jones 			 * 32-bit mode following a write operation.  The issue
116689818066SLee Jones 			 * is under investigation.
116789818066SLee Jones 			 */
116889818066SLee Jones 			fsm->configuration |= CFG_WRITE_EX_32BIT_ADDR_DELAY;
116989818066SLee Jones 		}
117089818066SLee Jones 	}
117189818066SLee Jones 
117289818066SLee Jones 	/* For QUAD mode, set 'QE' STATUS bit */
1173e6b1bb4eSLee Jones 	data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
117489818066SLee Jones 	if (data_pads == 4) {
117589818066SLee Jones 		stfsm_read_status(fsm, FLASH_CMD_RDSR, &sta);
117689818066SLee Jones 		sta |= MX25_STATUS_QE;
117789818066SLee Jones 		stfsm_write_status(fsm, sta, 1);
117889818066SLee Jones 	}
117989818066SLee Jones 
118089818066SLee Jones 	return 0;
118189818066SLee Jones }
118289818066SLee Jones 
1183218b870fSLee Jones static int stfsm_n25q_config(struct stfsm *fsm)
1184218b870fSLee Jones {
1185218b870fSLee Jones 	uint32_t flags = fsm->info->flags;
1186218b870fSLee Jones 	uint8_t vcr;
1187218b870fSLee Jones 	int ret = 0;
1188218b870fSLee Jones 	bool soc_reset;
1189218b870fSLee Jones 
1190218b870fSLee Jones 	/* Configure 'READ' sequence */
1191218b870fSLee Jones 	if (flags & FLASH_FLAG_32BIT_ADDR)
1192e6b1bb4eSLee Jones 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
1193218b870fSLee Jones 						  n25q_read4_configs);
1194218b870fSLee Jones 	else
1195e6b1bb4eSLee Jones 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
1196218b870fSLee Jones 						  n25q_read3_configs);
1197218b870fSLee Jones 	if (ret) {
1198218b870fSLee Jones 		dev_err(fsm->dev,
1199218b870fSLee Jones 			"failed to prepare READ sequence with flags [0x%08x]\n",
1200218b870fSLee Jones 			flags);
1201218b870fSLee Jones 		return ret;
1202218b870fSLee Jones 	}
1203218b870fSLee Jones 
1204218b870fSLee Jones 	/* Configure 'WRITE' sequence (default configs) */
1205e6b1bb4eSLee Jones 	ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
1206218b870fSLee Jones 					  default_write_configs);
1207218b870fSLee Jones 	if (ret) {
1208218b870fSLee Jones 		dev_err(fsm->dev,
1209218b870fSLee Jones 			"preparing WRITE sequence using flags [0x%08x] failed\n",
1210218b870fSLee Jones 			flags);
1211218b870fSLee Jones 		return ret;
1212218b870fSLee Jones 	}
1213218b870fSLee Jones 
1214218b870fSLee Jones 	/* * Configure 'ERASE_SECTOR' sequence */
1215218b870fSLee Jones 	stfsm_prepare_erasesec_seq(fsm, &stfsm_seq_erase_sector);
1216218b870fSLee Jones 
1217218b870fSLee Jones 	/* Configure 32-bit address support */
1218218b870fSLee Jones 	if (flags & FLASH_FLAG_32BIT_ADDR) {
1219e6b1bb4eSLee Jones 		stfsm_n25q_en_32bit_addr_seq(&fsm->stfsm_seq_en_32bit_addr);
1220218b870fSLee Jones 
1221218b870fSLee Jones 		soc_reset = stfsm_can_handle_soc_reset(fsm);
1222218b870fSLee Jones 		if (soc_reset || !fsm->booted_from_spi) {
1223218b870fSLee Jones 			/*
1224218b870fSLee Jones 			 * If we can handle SoC resets, we enable 32-bit
1225218b870fSLee Jones 			 * address mode pervasively
1226218b870fSLee Jones 			 */
1227218b870fSLee Jones 			stfsm_enter_32bit_addr(fsm, 1);
1228218b870fSLee Jones 		} else {
1229218b870fSLee Jones 			/*
1230218b870fSLee Jones 			 * If not, enable/disable for WRITE and ERASE
1231218b870fSLee Jones 			 * operations (READ uses special commands)
1232218b870fSLee Jones 			 */
1233218b870fSLee Jones 			fsm->configuration = (CFG_WRITE_TOGGLE_32BIT_ADDR |
1234218b870fSLee Jones 					      CFG_ERASESEC_TOGGLE_32BIT_ADDR);
1235218b870fSLee Jones 		}
1236218b870fSLee Jones 	}
1237218b870fSLee Jones 
1238218b870fSLee Jones 	/*
1239218b870fSLee Jones 	 * Configure device to use 8 dummy cycles
1240218b870fSLee Jones 	 */
1241218b870fSLee Jones 	vcr = (N25Q_VCR_DUMMY_CYCLES(8) | N25Q_VCR_XIP_DISABLED |
1242218b870fSLee Jones 	       N25Q_VCR_WRAP_CONT);
1243218b870fSLee Jones 	stfsm_wrvcr(fsm, vcr);
1244218b870fSLee Jones 
1245218b870fSLee Jones 	return 0;
1246218b870fSLee Jones }
1247218b870fSLee Jones 
12485343a123SLee Jones static void stfsm_s25fl_prepare_erasesec_seq_32(struct stfsm_seq *seq)
12495343a123SLee Jones {
12505343a123SLee Jones 	seq->seq_opc[1] = (SEQ_OPC_PADS_1 |
12515343a123SLee Jones 			   SEQ_OPC_CYCLES(8) |
12525343a123SLee Jones 			   SEQ_OPC_OPCODE(S25FL_CMD_SE4));
12535343a123SLee Jones 
12545343a123SLee Jones 	seq->addr_cfg = (ADR_CFG_CYCLES_ADD1(16) |
12555343a123SLee Jones 			 ADR_CFG_PADS_1_ADD1 |
12565343a123SLee Jones 			 ADR_CFG_CYCLES_ADD2(16) |
12575343a123SLee Jones 			 ADR_CFG_PADS_1_ADD2 |
12585343a123SLee Jones 			 ADR_CFG_CSDEASSERT_ADD2);
12595343a123SLee Jones }
12605343a123SLee Jones 
12615343a123SLee Jones static void stfsm_s25fl_read_dyb(struct stfsm *fsm, uint32_t offs, uint8_t *dby)
12625343a123SLee Jones {
12635343a123SLee Jones 	uint32_t tmp;
12645343a123SLee Jones 	struct stfsm_seq seq = {
12655343a123SLee Jones 		.data_size = TRANSFER_SIZE(4),
12665343a123SLee Jones 		.seq_opc[0] = (SEQ_OPC_PADS_1 |
12675343a123SLee Jones 			       SEQ_OPC_CYCLES(8) |
12685343a123SLee Jones 			       SEQ_OPC_OPCODE(S25FL_CMD_DYBRD)),
12695343a123SLee Jones 		.addr_cfg = (ADR_CFG_CYCLES_ADD1(16) |
12705343a123SLee Jones 			     ADR_CFG_PADS_1_ADD1 |
12715343a123SLee Jones 			     ADR_CFG_CYCLES_ADD2(16) |
12725343a123SLee Jones 			     ADR_CFG_PADS_1_ADD2),
12735343a123SLee Jones 		.addr1 = (offs >> 16) & 0xffff,
12745343a123SLee Jones 		.addr2 = offs & 0xffff,
12755343a123SLee Jones 		.seq = {
12765343a123SLee Jones 			STFSM_INST_CMD1,
12775343a123SLee Jones 			STFSM_INST_ADD1,
12785343a123SLee Jones 			STFSM_INST_ADD2,
12795343a123SLee Jones 			STFSM_INST_DATA_READ,
12805343a123SLee Jones 			STFSM_INST_STOP,
12815343a123SLee Jones 		},
12825343a123SLee Jones 		.seq_cfg = (SEQ_CFG_PADS_1 |
12835343a123SLee Jones 			    SEQ_CFG_READNOTWRITE |
12845343a123SLee Jones 			    SEQ_CFG_CSDEASSERT |
12855343a123SLee Jones 			    SEQ_CFG_STARTSEQ),
12865343a123SLee Jones 	};
12875343a123SLee Jones 
12885343a123SLee Jones 	stfsm_load_seq(fsm, &seq);
12895343a123SLee Jones 
12905343a123SLee Jones 	stfsm_read_fifo(fsm, &tmp, 4);
12915343a123SLee Jones 
12925343a123SLee Jones 	*dby = (uint8_t)(tmp >> 24);
12935343a123SLee Jones 
12945343a123SLee Jones 	stfsm_wait_seq(fsm);
12955343a123SLee Jones }
12965343a123SLee Jones 
12975343a123SLee Jones static void stfsm_s25fl_write_dyb(struct stfsm *fsm, uint32_t offs, uint8_t dby)
12985343a123SLee Jones {
12995343a123SLee Jones 	struct stfsm_seq seq = {
13005343a123SLee Jones 		.seq_opc[0] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
13015343a123SLee Jones 			       SEQ_OPC_OPCODE(FLASH_CMD_WREN) |
13025343a123SLee Jones 			       SEQ_OPC_CSDEASSERT),
13035343a123SLee Jones 		.seq_opc[1] = (SEQ_OPC_PADS_1 | SEQ_OPC_CYCLES(8) |
13045343a123SLee Jones 			       SEQ_OPC_OPCODE(S25FL_CMD_DYBWR)),
13055343a123SLee Jones 		.addr_cfg = (ADR_CFG_CYCLES_ADD1(16) |
13065343a123SLee Jones 			     ADR_CFG_PADS_1_ADD1 |
13075343a123SLee Jones 			     ADR_CFG_CYCLES_ADD2(16) |
13085343a123SLee Jones 			     ADR_CFG_PADS_1_ADD2),
13095343a123SLee Jones 		.status = (uint32_t)dby | STA_PADS_1 | STA_CSDEASSERT,
13105343a123SLee Jones 		.addr1 = (offs >> 16) & 0xffff,
13115343a123SLee Jones 		.addr2 = offs & 0xffff,
13125343a123SLee Jones 		.seq = {
13135343a123SLee Jones 			STFSM_INST_CMD1,
13145343a123SLee Jones 			STFSM_INST_CMD2,
13155343a123SLee Jones 			STFSM_INST_ADD1,
13165343a123SLee Jones 			STFSM_INST_ADD2,
13175343a123SLee Jones 			STFSM_INST_STA_WR1,
13185343a123SLee Jones 			STFSM_INST_STOP,
13195343a123SLee Jones 		},
13205343a123SLee Jones 		.seq_cfg = (SEQ_CFG_PADS_1 |
13215343a123SLee Jones 			    SEQ_CFG_READNOTWRITE |
13225343a123SLee Jones 			    SEQ_CFG_CSDEASSERT |
13235343a123SLee Jones 			    SEQ_CFG_STARTSEQ),
13245343a123SLee Jones 	};
13255343a123SLee Jones 
13265343a123SLee Jones 	stfsm_load_seq(fsm, &seq);
13275343a123SLee Jones 	stfsm_wait_seq(fsm);
13285343a123SLee Jones 
13295343a123SLee Jones 	stfsm_wait_busy(fsm);
13305343a123SLee Jones }
13315343a123SLee Jones 
13325343a123SLee Jones static int stfsm_s25fl_clear_status_reg(struct stfsm *fsm)
13335343a123SLee Jones {
13345343a123SLee Jones 	struct stfsm_seq seq = {
13355343a123SLee Jones 		.seq_opc[0] = (SEQ_OPC_PADS_1 |
13365343a123SLee Jones 			       SEQ_OPC_CYCLES(8) |
13375343a123SLee Jones 			       SEQ_OPC_OPCODE(S25FL_CMD_CLSR) |
13385343a123SLee Jones 			       SEQ_OPC_CSDEASSERT),
13395343a123SLee Jones 		.seq_opc[1] = (SEQ_OPC_PADS_1 |
13405343a123SLee Jones 			       SEQ_OPC_CYCLES(8) |
13415343a123SLee Jones 			       SEQ_OPC_OPCODE(FLASH_CMD_WRDI) |
13425343a123SLee Jones 			       SEQ_OPC_CSDEASSERT),
13435343a123SLee Jones 		.seq = {
13445343a123SLee Jones 			STFSM_INST_CMD1,
13455343a123SLee Jones 			STFSM_INST_CMD2,
13465343a123SLee Jones 			STFSM_INST_WAIT,
13475343a123SLee Jones 			STFSM_INST_STOP,
13485343a123SLee Jones 		},
13495343a123SLee Jones 		.seq_cfg = (SEQ_CFG_PADS_1 |
13505343a123SLee Jones 			    SEQ_CFG_ERASE |
13515343a123SLee Jones 			    SEQ_CFG_READNOTWRITE |
13525343a123SLee Jones 			    SEQ_CFG_CSDEASSERT |
13535343a123SLee Jones 			    SEQ_CFG_STARTSEQ),
13545343a123SLee Jones 	};
13555343a123SLee Jones 
13565343a123SLee Jones 	stfsm_load_seq(fsm, &seq);
13575343a123SLee Jones 
13585343a123SLee Jones 	stfsm_wait_seq(fsm);
13595343a123SLee Jones 
13605343a123SLee Jones 	return 0;
13615343a123SLee Jones }
13625343a123SLee Jones 
13635343a123SLee Jones static int stfsm_s25fl_config(struct stfsm *fsm)
13645343a123SLee Jones {
13655343a123SLee Jones 	struct flash_info *info = fsm->info;
13665343a123SLee Jones 	uint32_t flags = info->flags;
13675343a123SLee Jones 	uint32_t data_pads;
13685343a123SLee Jones 	uint32_t offs;
13695343a123SLee Jones 	uint16_t sta_wr;
13705343a123SLee Jones 	uint8_t sr1, cr1, dyb;
13715343a123SLee Jones 	int ret;
13725343a123SLee Jones 
13735343a123SLee Jones 	if (flags & FLASH_FLAG_32BIT_ADDR) {
13745343a123SLee Jones 		/*
13755343a123SLee Jones 		 * Prepare Read/Write/Erase sequences according to S25FLxxx
13765343a123SLee Jones 		 * 32-bit address command set
13775343a123SLee Jones 		 */
1378e6b1bb4eSLee Jones 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_read,
13795343a123SLee Jones 						  stfsm_s25fl_read4_configs);
13805343a123SLee Jones 		if (ret)
13815343a123SLee Jones 			return ret;
13825343a123SLee Jones 
1383e6b1bb4eSLee Jones 		ret = stfsm_search_prepare_rw_seq(fsm, &fsm->stfsm_seq_write,
13845343a123SLee Jones 						  stfsm_s25fl_write4_configs);
13855343a123SLee Jones 		if (ret)
13865343a123SLee Jones 			return ret;
13875343a123SLee Jones 
13885343a123SLee Jones 		stfsm_s25fl_prepare_erasesec_seq_32(&stfsm_seq_erase_sector);
13895343a123SLee Jones 
13905343a123SLee Jones 	} else {
13915343a123SLee Jones 		/* Use default configurations for 24-bit addressing */
13925343a123SLee Jones 		ret = stfsm_prepare_rwe_seqs_default(fsm);
13935343a123SLee Jones 		if (ret)
13945343a123SLee Jones 			return ret;
13955343a123SLee Jones 	}
13965343a123SLee Jones 
13975343a123SLee Jones 	/*
13985343a123SLee Jones 	 * For devices that support 'DYB' sector locking, check lock status and
13995343a123SLee Jones 	 * unlock sectors if necessary (some variants power-on with sectors
14005343a123SLee Jones 	 * locked by default)
14015343a123SLee Jones 	 */
14025343a123SLee Jones 	if (flags & FLASH_FLAG_DYB_LOCKING) {
14035343a123SLee Jones 		offs = 0;
14045343a123SLee Jones 		for (offs = 0; offs < info->sector_size * info->n_sectors;) {
14055343a123SLee Jones 			stfsm_s25fl_read_dyb(fsm, offs, &dyb);
14065343a123SLee Jones 			if (dyb == 0x00)
14075343a123SLee Jones 				stfsm_s25fl_write_dyb(fsm, offs, 0xff);
14085343a123SLee Jones 
14095343a123SLee Jones 			/* Handle bottom/top 4KiB parameter sectors */
14105343a123SLee Jones 			if ((offs < info->sector_size * 2) ||
14115343a123SLee Jones 			    (offs >= (info->sector_size - info->n_sectors * 4)))
14125343a123SLee Jones 				offs += 0x1000;
14135343a123SLee Jones 			else
14145343a123SLee Jones 				offs += 0x10000;
14155343a123SLee Jones 		}
14165343a123SLee Jones 	}
14175343a123SLee Jones 
14185343a123SLee Jones 	/* Check status of 'QE' bit */
1419e6b1bb4eSLee Jones 	data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
14205343a123SLee Jones 	stfsm_read_status(fsm, FLASH_CMD_RDSR2, &cr1);
14215343a123SLee Jones 	if (data_pads == 4) {
14225343a123SLee Jones 		if (!(cr1 & STFSM_S25FL_CONFIG_QE)) {
14235343a123SLee Jones 			/* Set 'QE' */
14245343a123SLee Jones 			cr1 |= STFSM_S25FL_CONFIG_QE;
14255343a123SLee Jones 
14265343a123SLee Jones 			stfsm_read_status(fsm, FLASH_CMD_RDSR, &sr1);
14275343a123SLee Jones 			sta_wr = ((uint16_t)cr1  << 8) | sr1;
14285343a123SLee Jones 
14295343a123SLee Jones 			stfsm_write_status(fsm, sta_wr, 2);
14305343a123SLee Jones 
14315343a123SLee Jones 			stfsm_wait_busy(fsm);
14325343a123SLee Jones 		}
14335343a123SLee Jones 	} else {
14345343a123SLee Jones 		if ((cr1 & STFSM_S25FL_CONFIG_QE)) {
14355343a123SLee Jones 			/* Clear 'QE' */
14365343a123SLee Jones 			cr1 &= ~STFSM_S25FL_CONFIG_QE;
14375343a123SLee Jones 
14385343a123SLee Jones 			stfsm_read_status(fsm, FLASH_CMD_RDSR, &sr1);
14395343a123SLee Jones 			sta_wr = ((uint16_t)cr1  << 8) | sr1;
14405343a123SLee Jones 
14415343a123SLee Jones 			stfsm_write_status(fsm, sta_wr, 2);
14425343a123SLee Jones 
14435343a123SLee Jones 			stfsm_wait_busy(fsm);
14445343a123SLee Jones 		}
14455343a123SLee Jones 
14465343a123SLee Jones 	}
14475343a123SLee Jones 
14485343a123SLee Jones 	/*
14495343a123SLee Jones 	 * S25FLxxx devices support Program and Error error flags.
14505343a123SLee Jones 	 * Configure driver to check flags and clear if necessary.
14515343a123SLee Jones 	 */
14525343a123SLee Jones 	fsm->configuration |= CFG_S25FL_CHECK_ERROR_FLAGS;
14535343a123SLee Jones 
14545343a123SLee Jones 	return 0;
14555343a123SLee Jones }
14565343a123SLee Jones 
1457cd7cac9eSLee Jones static int stfsm_w25q_config(struct stfsm *fsm)
1458cd7cac9eSLee Jones {
1459cd7cac9eSLee Jones 	uint32_t data_pads;
1460cd7cac9eSLee Jones 	uint16_t sta_wr;
1461cd7cac9eSLee Jones 	uint8_t sta1, sta2;
1462cd7cac9eSLee Jones 	int ret;
1463cd7cac9eSLee Jones 
1464cd7cac9eSLee Jones 	ret = stfsm_prepare_rwe_seqs_default(fsm);
1465cd7cac9eSLee Jones 	if (ret)
1466cd7cac9eSLee Jones 		return ret;
1467cd7cac9eSLee Jones 
1468cd7cac9eSLee Jones 	/* If using QUAD mode, set QE STATUS bit */
1469e6b1bb4eSLee Jones 	data_pads = ((fsm->stfsm_seq_read.seq_cfg >> 16) & 0x3) + 1;
1470cd7cac9eSLee Jones 	if (data_pads == 4) {
1471cd7cac9eSLee Jones 		stfsm_read_status(fsm, FLASH_CMD_RDSR, &sta1);
1472cd7cac9eSLee Jones 		stfsm_read_status(fsm, FLASH_CMD_RDSR2, &sta2);
1473cd7cac9eSLee Jones 
1474cd7cac9eSLee Jones 		sta_wr = ((uint16_t)sta2 << 8) | sta1;
1475cd7cac9eSLee Jones 
1476cd7cac9eSLee Jones 		sta_wr |= W25Q_STATUS_QE;
1477cd7cac9eSLee Jones 
1478cd7cac9eSLee Jones 		stfsm_write_status(fsm, sta_wr, 2);
1479cd7cac9eSLee Jones 
1480cd7cac9eSLee Jones 		stfsm_wait_busy(fsm);
1481cd7cac9eSLee Jones 	}
1482cd7cac9eSLee Jones 
1483cd7cac9eSLee Jones 	return 0;
1484cd7cac9eSLee Jones }
1485cd7cac9eSLee Jones 
1486e514f105SLee Jones static int stfsm_read(struct stfsm *fsm, uint8_t *buf, uint32_t size,
1487e514f105SLee Jones 		      uint32_t offset)
1488e514f105SLee Jones {
1489e6b1bb4eSLee Jones 	struct stfsm_seq *seq = &fsm->stfsm_seq_read;
1490e514f105SLee Jones 	uint32_t data_pads;
1491e514f105SLee Jones 	uint32_t read_mask;
1492e514f105SLee Jones 	uint32_t size_ub;
1493e514f105SLee Jones 	uint32_t size_lb;
1494e514f105SLee Jones 	uint32_t size_mop;
1495e514f105SLee Jones 	uint32_t tmp[4];
1496e514f105SLee Jones 	uint32_t page_buf[FLASH_PAGESIZE_32];
1497e514f105SLee Jones 	uint8_t *p;
1498e514f105SLee Jones 
1499e514f105SLee Jones 	dev_dbg(fsm->dev, "reading %d bytes from 0x%08x\n", size, offset);
1500e514f105SLee Jones 
1501e514f105SLee Jones 	/* Enter 32-bit address mode, if required */
1502e514f105SLee Jones 	if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR)
1503e514f105SLee Jones 		stfsm_enter_32bit_addr(fsm, 1);
1504e514f105SLee Jones 
1505e514f105SLee Jones 	/* Must read in multiples of 32 cycles (or 32*pads/8 Bytes) */
1506e514f105SLee Jones 	data_pads = ((seq->seq_cfg >> 16) & 0x3) + 1;
1507e514f105SLee Jones 	read_mask = (data_pads << 2) - 1;
1508e514f105SLee Jones 
1509e514f105SLee Jones 	/* Handle non-aligned buf */
1510e514f105SLee Jones 	p = ((uint32_t)buf & 0x3) ? (uint8_t *)page_buf : buf;
1511e514f105SLee Jones 
1512e514f105SLee Jones 	/* Handle non-aligned size */
1513e514f105SLee Jones 	size_ub = (size + read_mask) & ~read_mask;
1514e514f105SLee Jones 	size_lb = size & ~read_mask;
1515e514f105SLee Jones 	size_mop = size & read_mask;
1516e514f105SLee Jones 
1517e514f105SLee Jones 	seq->data_size = TRANSFER_SIZE(size_ub);
1518e514f105SLee Jones 	seq->addr1 = (offset >> 16) & 0xffff;
1519e514f105SLee Jones 	seq->addr2 = offset & 0xffff;
1520e514f105SLee Jones 
1521e514f105SLee Jones 	stfsm_load_seq(fsm, seq);
1522e514f105SLee Jones 
1523e514f105SLee Jones 	if (size_lb)
1524e514f105SLee Jones 		stfsm_read_fifo(fsm, (uint32_t *)p, size_lb);
1525e514f105SLee Jones 
1526e514f105SLee Jones 	if (size_mop) {
1527e514f105SLee Jones 		stfsm_read_fifo(fsm, tmp, read_mask + 1);
1528e514f105SLee Jones 		memcpy(p + size_lb, &tmp, size_mop);
1529e514f105SLee Jones 	}
1530e514f105SLee Jones 
1531e514f105SLee Jones 	/* Handle non-aligned buf */
1532e514f105SLee Jones 	if ((uint32_t)buf & 0x3)
1533e514f105SLee Jones 		memcpy(buf, page_buf, size);
1534e514f105SLee Jones 
1535e514f105SLee Jones 	/* Wait for sequence to finish */
1536e514f105SLee Jones 	stfsm_wait_seq(fsm);
1537e514f105SLee Jones 
1538e514f105SLee Jones 	stfsm_clear_fifo(fsm);
1539e514f105SLee Jones 
1540e514f105SLee Jones 	/* Exit 32-bit address mode, if required */
1541e514f105SLee Jones 	if (fsm->configuration & CFG_READ_TOGGLE_32BIT_ADDR)
1542e514f105SLee Jones 		stfsm_enter_32bit_addr(fsm, 0);
1543e514f105SLee Jones 
1544e514f105SLee Jones 	return 0;
1545e514f105SLee Jones }
1546e514f105SLee Jones 
1547176b4377SLee Jones static int stfsm_write(struct stfsm *fsm, const uint8_t *const buf,
1548176b4377SLee Jones 		       const uint32_t size, const uint32_t offset)
1549176b4377SLee Jones {
1550e6b1bb4eSLee Jones 	struct stfsm_seq *seq = &fsm->stfsm_seq_write;
1551176b4377SLee Jones 	uint32_t data_pads;
1552176b4377SLee Jones 	uint32_t write_mask;
1553176b4377SLee Jones 	uint32_t size_ub;
1554176b4377SLee Jones 	uint32_t size_lb;
1555176b4377SLee Jones 	uint32_t size_mop;
1556176b4377SLee Jones 	uint32_t tmp[4];
1557176b4377SLee Jones 	uint32_t page_buf[FLASH_PAGESIZE_32];
1558176b4377SLee Jones 	uint8_t *t = (uint8_t *)&tmp;
1559176b4377SLee Jones 	const uint8_t *p;
1560176b4377SLee Jones 	int ret;
1561176b4377SLee Jones 	int i;
1562176b4377SLee Jones 
1563176b4377SLee Jones 	dev_dbg(fsm->dev, "writing %d bytes to 0x%08x\n", size, offset);
1564176b4377SLee Jones 
1565176b4377SLee Jones 	/* Enter 32-bit address mode, if required */
1566176b4377SLee Jones 	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR)
1567176b4377SLee Jones 		stfsm_enter_32bit_addr(fsm, 1);
1568176b4377SLee Jones 
1569176b4377SLee Jones 	/* Must write in multiples of 32 cycles (or 32*pads/8 bytes) */
1570176b4377SLee Jones 	data_pads = ((seq->seq_cfg >> 16) & 0x3) + 1;
1571176b4377SLee Jones 	write_mask = (data_pads << 2) - 1;
1572176b4377SLee Jones 
1573176b4377SLee Jones 	/* Handle non-aligned buf */
1574176b4377SLee Jones 	if ((uint32_t)buf & 0x3) {
1575176b4377SLee Jones 		memcpy(page_buf, buf, size);
1576176b4377SLee Jones 		p = (uint8_t *)page_buf;
1577176b4377SLee Jones 	} else {
1578176b4377SLee Jones 		p = buf;
1579176b4377SLee Jones 	}
1580176b4377SLee Jones 
1581176b4377SLee Jones 	/* Handle non-aligned size */
1582176b4377SLee Jones 	size_ub = (size + write_mask) & ~write_mask;
1583176b4377SLee Jones 	size_lb = size & ~write_mask;
1584176b4377SLee Jones 	size_mop = size & write_mask;
1585176b4377SLee Jones 
1586176b4377SLee Jones 	seq->data_size = TRANSFER_SIZE(size_ub);
1587176b4377SLee Jones 	seq->addr1 = (offset >> 16) & 0xffff;
1588176b4377SLee Jones 	seq->addr2 = offset & 0xffff;
1589176b4377SLee Jones 
1590176b4377SLee Jones 	/* Need to set FIFO to write mode, before writing data to FIFO (see
1591176b4377SLee Jones 	 * GNBvb79594)
1592176b4377SLee Jones 	 */
1593176b4377SLee Jones 	writel(0x00040000, fsm->base + SPI_FAST_SEQ_CFG);
1594176b4377SLee Jones 
1595176b4377SLee Jones 	/*
1596176b4377SLee Jones 	 * Before writing data to the FIFO, apply a small delay to allow a
1597176b4377SLee Jones 	 * potential change of FIFO direction to complete.
1598176b4377SLee Jones 	 */
1599176b4377SLee Jones 	if (fsm->fifo_dir_delay == 0)
1600176b4377SLee Jones 		readl(fsm->base + SPI_FAST_SEQ_CFG);
1601176b4377SLee Jones 	else
1602176b4377SLee Jones 		udelay(fsm->fifo_dir_delay);
1603176b4377SLee Jones 
1604176b4377SLee Jones 
1605176b4377SLee Jones 	/* Write data to FIFO, before starting sequence (see GNBvd79593) */
1606176b4377SLee Jones 	if (size_lb) {
1607176b4377SLee Jones 		stfsm_write_fifo(fsm, (uint32_t *)p, size_lb);
1608176b4377SLee Jones 		p += size_lb;
1609176b4377SLee Jones 	}
1610176b4377SLee Jones 
1611176b4377SLee Jones 	/* Handle non-aligned size */
1612176b4377SLee Jones 	if (size_mop) {
1613176b4377SLee Jones 		memset(t, 0xff, write_mask + 1);	/* fill with 0xff's */
1614176b4377SLee Jones 		for (i = 0; i < size_mop; i++)
1615176b4377SLee Jones 			t[i] = *p++;
1616176b4377SLee Jones 
1617176b4377SLee Jones 		stfsm_write_fifo(fsm, tmp, write_mask + 1);
1618176b4377SLee Jones 	}
1619176b4377SLee Jones 
1620176b4377SLee Jones 	/* Start sequence */
1621176b4377SLee Jones 	stfsm_load_seq(fsm, seq);
1622176b4377SLee Jones 
1623176b4377SLee Jones 	/* Wait for sequence to finish */
1624176b4377SLee Jones 	stfsm_wait_seq(fsm);
1625176b4377SLee Jones 
1626176b4377SLee Jones 	/* Wait for completion */
1627176b4377SLee Jones 	ret = stfsm_wait_busy(fsm);
16285343a123SLee Jones 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
16295343a123SLee Jones 		stfsm_s25fl_clear_status_reg(fsm);
1630176b4377SLee Jones 
1631176b4377SLee Jones 	/* Exit 32-bit address mode, if required */
1632176b4377SLee Jones 	if (fsm->configuration & CFG_WRITE_TOGGLE_32BIT_ADDR) {
1633176b4377SLee Jones 		stfsm_enter_32bit_addr(fsm, 0);
1634176b4377SLee Jones 		if (fsm->configuration & CFG_WRITE_EX_32BIT_ADDR_DELAY)
1635176b4377SLee Jones 			udelay(1);
1636176b4377SLee Jones 	}
1637176b4377SLee Jones 
1638176b4377SLee Jones 	return 0;
1639176b4377SLee Jones }
1640176b4377SLee Jones 
1641e514f105SLee Jones /*
1642e514f105SLee Jones  * Read an address range from the flash chip. The address range
1643e514f105SLee Jones  * may be any size provided it is within the physical boundaries.
1644e514f105SLee Jones  */
1645e514f105SLee Jones static int stfsm_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
1646e514f105SLee Jones 			  size_t *retlen, u_char *buf)
1647e514f105SLee Jones {
1648e514f105SLee Jones 	struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
1649e514f105SLee Jones 	uint32_t bytes;
1650e514f105SLee Jones 
1651e514f105SLee Jones 	dev_dbg(fsm->dev, "%s from 0x%08x, len %zd\n",
1652e514f105SLee Jones 		__func__, (u32)from, len);
1653e514f105SLee Jones 
1654e514f105SLee Jones 	mutex_lock(&fsm->lock);
1655e514f105SLee Jones 
1656e514f105SLee Jones 	while (len > 0) {
1657e514f105SLee Jones 		bytes = min_t(size_t, len, FLASH_PAGESIZE);
1658e514f105SLee Jones 
1659e514f105SLee Jones 		stfsm_read(fsm, buf, bytes, from);
1660e514f105SLee Jones 
1661e514f105SLee Jones 		buf += bytes;
1662e514f105SLee Jones 		from += bytes;
1663e514f105SLee Jones 		len -= bytes;
1664e514f105SLee Jones 
1665e514f105SLee Jones 		*retlen += bytes;
1666e514f105SLee Jones 	}
1667e514f105SLee Jones 
1668e514f105SLee Jones 	mutex_unlock(&fsm->lock);
1669e514f105SLee Jones 
1670e514f105SLee Jones 	return 0;
1671e514f105SLee Jones }
1672e514f105SLee Jones 
16734a341fe7SLee Jones static int stfsm_erase_sector(struct stfsm *fsm, const uint32_t offset)
16744a341fe7SLee Jones {
16754a341fe7SLee Jones 	struct stfsm_seq *seq = &stfsm_seq_erase_sector;
16764a341fe7SLee Jones 	int ret;
16774a341fe7SLee Jones 
16784a341fe7SLee Jones 	dev_dbg(fsm->dev, "erasing sector at 0x%08x\n", offset);
16794a341fe7SLee Jones 
16804a341fe7SLee Jones 	/* Enter 32-bit address mode, if required */
16814a341fe7SLee Jones 	if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
16824a341fe7SLee Jones 		stfsm_enter_32bit_addr(fsm, 1);
16834a341fe7SLee Jones 
16844a341fe7SLee Jones 	seq->addr1 = (offset >> 16) & 0xffff;
16854a341fe7SLee Jones 	seq->addr2 = offset & 0xffff;
16864a341fe7SLee Jones 
16874a341fe7SLee Jones 	stfsm_load_seq(fsm, seq);
16884a341fe7SLee Jones 
16894a341fe7SLee Jones 	stfsm_wait_seq(fsm);
16904a341fe7SLee Jones 
16914a341fe7SLee Jones 	/* Wait for completion */
16924a341fe7SLee Jones 	ret = stfsm_wait_busy(fsm);
16935343a123SLee Jones 	if (ret && fsm->configuration & CFG_S25FL_CHECK_ERROR_FLAGS)
16945343a123SLee Jones 		stfsm_s25fl_clear_status_reg(fsm);
16954a341fe7SLee Jones 
16964a341fe7SLee Jones 	/* Exit 32-bit address mode, if required */
16974a341fe7SLee Jones 	if (fsm->configuration & CFG_ERASESEC_TOGGLE_32BIT_ADDR)
16984a341fe7SLee Jones 		stfsm_enter_32bit_addr(fsm, 0);
16994a341fe7SLee Jones 
17004a341fe7SLee Jones 	return ret;
17014a341fe7SLee Jones }
17024a341fe7SLee Jones 
17034a341fe7SLee Jones static int stfsm_erase_chip(struct stfsm *fsm)
17044a341fe7SLee Jones {
17054a341fe7SLee Jones 	const struct stfsm_seq *seq = &stfsm_seq_erase_chip;
17064a341fe7SLee Jones 
17074a341fe7SLee Jones 	dev_dbg(fsm->dev, "erasing chip\n");
17084a341fe7SLee Jones 
17094a341fe7SLee Jones 	stfsm_load_seq(fsm, seq);
17104a341fe7SLee Jones 
17114a341fe7SLee Jones 	stfsm_wait_seq(fsm);
17124a341fe7SLee Jones 
17134a341fe7SLee Jones 	return stfsm_wait_busy(fsm);
17144a341fe7SLee Jones }
17154a341fe7SLee Jones 
1716176b4377SLee Jones /*
1717176b4377SLee Jones  * Write an address range to the flash chip.  Data must be written in
1718176b4377SLee Jones  * FLASH_PAGESIZE chunks.  The address range may be any size provided
1719176b4377SLee Jones  * it is within the physical boundaries.
1720176b4377SLee Jones  */
1721176b4377SLee Jones static int stfsm_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
1722176b4377SLee Jones 			   size_t *retlen, const u_char *buf)
1723176b4377SLee Jones {
1724176b4377SLee Jones 	struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
1725176b4377SLee Jones 
1726176b4377SLee Jones 	u32 page_offs;
1727176b4377SLee Jones 	u32 bytes;
1728176b4377SLee Jones 	uint8_t *b = (uint8_t *)buf;
1729176b4377SLee Jones 	int ret = 0;
1730176b4377SLee Jones 
1731176b4377SLee Jones 	dev_dbg(fsm->dev, "%s to 0x%08x, len %zd\n", __func__, (u32)to, len);
1732176b4377SLee Jones 
1733176b4377SLee Jones 	*retlen = 0;
1734176b4377SLee Jones 
1735176b4377SLee Jones 	if (!len)
1736176b4377SLee Jones 		return 0;
1737176b4377SLee Jones 
1738176b4377SLee Jones 	if (to + len > mtd->size)
1739176b4377SLee Jones 		return -EINVAL;
1740176b4377SLee Jones 
1741176b4377SLee Jones 	/* Offset within page */
1742176b4377SLee Jones 	page_offs = to % FLASH_PAGESIZE;
1743176b4377SLee Jones 
1744176b4377SLee Jones 	mutex_lock(&fsm->lock);
1745176b4377SLee Jones 
1746176b4377SLee Jones 	while (len) {
1747176b4377SLee Jones 		/* Write up to page boundary */
1748176b4377SLee Jones 		bytes = min(FLASH_PAGESIZE - page_offs, len);
1749176b4377SLee Jones 
1750176b4377SLee Jones 		ret = stfsm_write(fsm, b, bytes, to);
1751176b4377SLee Jones 		if (ret)
1752176b4377SLee Jones 			goto out1;
1753176b4377SLee Jones 
1754176b4377SLee Jones 		b += bytes;
1755176b4377SLee Jones 		len -= bytes;
1756176b4377SLee Jones 		to += bytes;
1757176b4377SLee Jones 
1758176b4377SLee Jones 		/* We are now page-aligned */
1759176b4377SLee Jones 		page_offs = 0;
1760176b4377SLee Jones 
1761176b4377SLee Jones 		*retlen += bytes;
1762176b4377SLee Jones 
1763176b4377SLee Jones 	}
1764176b4377SLee Jones 
1765176b4377SLee Jones out1:
1766176b4377SLee Jones 	mutex_unlock(&fsm->lock);
1767176b4377SLee Jones 
1768176b4377SLee Jones 	return ret;
1769176b4377SLee Jones }
1770176b4377SLee Jones 
17714a341fe7SLee Jones /*
17724a341fe7SLee Jones  * Erase an address range on the flash chip. The address range may extend
17734a341fe7SLee Jones  * one or more erase sectors.  Return an error is there is a problem erasing.
17744a341fe7SLee Jones  */
17754a341fe7SLee Jones static int stfsm_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
17764a341fe7SLee Jones {
17774a341fe7SLee Jones 	struct stfsm *fsm = dev_get_drvdata(mtd->dev.parent);
17784a341fe7SLee Jones 	u32 addr, len;
17794a341fe7SLee Jones 	int ret;
17804a341fe7SLee Jones 
17814a341fe7SLee Jones 	dev_dbg(fsm->dev, "%s at 0x%llx, len %lld\n", __func__,
17824a341fe7SLee Jones 		(long long)instr->addr, (long long)instr->len);
17834a341fe7SLee Jones 
17844a341fe7SLee Jones 	addr = instr->addr;
17854a341fe7SLee Jones 	len = instr->len;
17864a341fe7SLee Jones 
17874a341fe7SLee Jones 	mutex_lock(&fsm->lock);
17884a341fe7SLee Jones 
17894a341fe7SLee Jones 	/* Whole-chip erase? */
17904a341fe7SLee Jones 	if (len == mtd->size) {
17914a341fe7SLee Jones 		ret = stfsm_erase_chip(fsm);
17924a341fe7SLee Jones 		if (ret)
17934a341fe7SLee Jones 			goto out1;
17944a341fe7SLee Jones 	} else {
17954a341fe7SLee Jones 		while (len) {
17964a341fe7SLee Jones 			ret = stfsm_erase_sector(fsm, addr);
17974a341fe7SLee Jones 			if (ret)
17984a341fe7SLee Jones 				goto out1;
17994a341fe7SLee Jones 
18004a341fe7SLee Jones 			addr += mtd->erasesize;
18014a341fe7SLee Jones 			len -= mtd->erasesize;
18024a341fe7SLee Jones 		}
18034a341fe7SLee Jones 	}
18044a341fe7SLee Jones 
18054a341fe7SLee Jones 	mutex_unlock(&fsm->lock);
18064a341fe7SLee Jones 
18074a341fe7SLee Jones 	instr->state = MTD_ERASE_DONE;
18084a341fe7SLee Jones 	mtd_erase_callback(instr);
18094a341fe7SLee Jones 
18104a341fe7SLee Jones 	return 0;
18114a341fe7SLee Jones 
18124a341fe7SLee Jones out1:
18134a341fe7SLee Jones 	instr->state = MTD_ERASE_FAILED;
18144a341fe7SLee Jones 	mutex_unlock(&fsm->lock);
18154a341fe7SLee Jones 
18164a341fe7SLee Jones 	return ret;
18174a341fe7SLee Jones }
18184a341fe7SLee Jones 
18191bd512b5SLee Jones static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
18201bd512b5SLee Jones {
18211bd512b5SLee Jones 	const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
18221bd512b5SLee Jones 	uint32_t tmp[2];
18231bd512b5SLee Jones 
18241bd512b5SLee Jones 	stfsm_load_seq(fsm, seq);
18251bd512b5SLee Jones 
18261bd512b5SLee Jones 	stfsm_read_fifo(fsm, tmp, 8);
18271bd512b5SLee Jones 
18281bd512b5SLee Jones 	memcpy(jedec, tmp, 5);
18291bd512b5SLee Jones 
18301bd512b5SLee Jones 	stfsm_wait_seq(fsm);
18311bd512b5SLee Jones }
18321bd512b5SLee Jones 
18331bd512b5SLee Jones static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
18341bd512b5SLee Jones {
183524fec651SLee Jones 	struct flash_info	*info;
18361bd512b5SLee Jones 	u16                     ext_jedec;
18371bd512b5SLee Jones 	u32			jedec;
18381bd512b5SLee Jones 	u8			id[5];
18391bd512b5SLee Jones 
18401bd512b5SLee Jones 	stfsm_read_jedec(fsm, id);
18411bd512b5SLee Jones 
18421bd512b5SLee Jones 	jedec     = id[0] << 16 | id[1] << 8 | id[2];
18431bd512b5SLee Jones 	/*
18441bd512b5SLee Jones 	 * JEDEC also defines an optional "extended device information"
18451bd512b5SLee Jones 	 * string for after vendor-specific data, after the three bytes
18461bd512b5SLee Jones 	 * we use here. Supporting some chips might require using it.
18471bd512b5SLee Jones 	 */
18481bd512b5SLee Jones 	ext_jedec = id[3] << 8  | id[4];
18491bd512b5SLee Jones 
18501bd512b5SLee Jones 	dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
18511bd512b5SLee Jones 		jedec, id[0], id[1], id[2], id[3], id[4]);
18521bd512b5SLee Jones 
185324fec651SLee Jones 	for (info = flash_types; info->name; info++) {
185424fec651SLee Jones 		if (info->jedec_id == jedec) {
185524fec651SLee Jones 			if (info->ext_id && info->ext_id != ext_jedec)
185624fec651SLee Jones 				continue;
185724fec651SLee Jones 			return info;
185824fec651SLee Jones 		}
185924fec651SLee Jones 	}
186024fec651SLee Jones 	dev_err(fsm->dev, "Unrecognized JEDEC id %06x\n", jedec);
186124fec651SLee Jones 
18621bd512b5SLee Jones 	return NULL;
18631bd512b5SLee Jones }
18641bd512b5SLee Jones 
186586f309fdSLee Jones static int stfsm_set_mode(struct stfsm *fsm, uint32_t mode)
186686f309fdSLee Jones {
186786f309fdSLee Jones 	int ret, timeout = 10;
186886f309fdSLee Jones 
186986f309fdSLee Jones 	/* Wait for controller to accept mode change */
187086f309fdSLee Jones 	while (--timeout) {
187186f309fdSLee Jones 		ret = readl(fsm->base + SPI_STA_MODE_CHANGE);
187286f309fdSLee Jones 		if (ret & 0x1)
187386f309fdSLee Jones 			break;
187486f309fdSLee Jones 		udelay(1);
187586f309fdSLee Jones 	}
187686f309fdSLee Jones 
187786f309fdSLee Jones 	if (!timeout)
187886f309fdSLee Jones 		return -EBUSY;
187986f309fdSLee Jones 
188086f309fdSLee Jones 	writel(mode, fsm->base + SPI_MODESELECT);
188186f309fdSLee Jones 
188286f309fdSLee Jones 	return 0;
188386f309fdSLee Jones }
188486f309fdSLee Jones 
188586f309fdSLee Jones static void stfsm_set_freq(struct stfsm *fsm, uint32_t spi_freq)
188686f309fdSLee Jones {
188786f309fdSLee Jones 	uint32_t emi_freq;
188886f309fdSLee Jones 	uint32_t clk_div;
188986f309fdSLee Jones 
189086f309fdSLee Jones 	/* TODO: Make this dynamic */
189186f309fdSLee Jones 	emi_freq = STFSM_DEFAULT_EMI_FREQ;
189286f309fdSLee Jones 
189386f309fdSLee Jones 	/*
189486f309fdSLee Jones 	 * Calculate clk_div - values between 2 and 128
189586f309fdSLee Jones 	 * Multiple of 2, rounded up
189686f309fdSLee Jones 	 */
189786f309fdSLee Jones 	clk_div = 2 * DIV_ROUND_UP(emi_freq, 2 * spi_freq);
189886f309fdSLee Jones 	if (clk_div < 2)
189986f309fdSLee Jones 		clk_div = 2;
190086f309fdSLee Jones 	else if (clk_div > 128)
190186f309fdSLee Jones 		clk_div = 128;
190286f309fdSLee Jones 
190386f309fdSLee Jones 	/*
190486f309fdSLee Jones 	 * Determine a suitable delay for the IP to complete a change of
190586f309fdSLee Jones 	 * direction of the FIFO. The required delay is related to the clock
190686f309fdSLee Jones 	 * divider used. The following heuristics are based on empirical tests,
190786f309fdSLee Jones 	 * using a 100MHz EMI clock.
190886f309fdSLee Jones 	 */
190986f309fdSLee Jones 	if (clk_div <= 4)
191086f309fdSLee Jones 		fsm->fifo_dir_delay = 0;
191186f309fdSLee Jones 	else if (clk_div <= 10)
191286f309fdSLee Jones 		fsm->fifo_dir_delay = 1;
191386f309fdSLee Jones 	else
191486f309fdSLee Jones 		fsm->fifo_dir_delay = DIV_ROUND_UP(clk_div, 10);
191586f309fdSLee Jones 
191686f309fdSLee Jones 	dev_dbg(fsm->dev, "emi_clk = %uHZ, spi_freq = %uHZ, clk_div = %u\n",
191786f309fdSLee Jones 		emi_freq, spi_freq, clk_div);
191886f309fdSLee Jones 
191986f309fdSLee Jones 	writel(clk_div, fsm->base + SPI_CLOCKDIV);
192086f309fdSLee Jones }
192186f309fdSLee Jones 
192286f309fdSLee Jones static int stfsm_init(struct stfsm *fsm)
192386f309fdSLee Jones {
192486f309fdSLee Jones 	int ret;
192586f309fdSLee Jones 
192686f309fdSLee Jones 	/* Perform a soft reset of the FSM controller */
192786f309fdSLee Jones 	writel(SEQ_CFG_SWRESET, fsm->base + SPI_FAST_SEQ_CFG);
192886f309fdSLee Jones 	udelay(1);
192986f309fdSLee Jones 	writel(0, fsm->base + SPI_FAST_SEQ_CFG);
193086f309fdSLee Jones 
193186f309fdSLee Jones 	/* Set clock to 'safe' frequency initially */
193286f309fdSLee Jones 	stfsm_set_freq(fsm, STFSM_FLASH_SAFE_FREQ);
193386f309fdSLee Jones 
193486f309fdSLee Jones 	/* Switch to FSM */
193586f309fdSLee Jones 	ret = stfsm_set_mode(fsm, SPI_MODESELECT_FSM);
193686f309fdSLee Jones 	if (ret)
193786f309fdSLee Jones 		return ret;
193886f309fdSLee Jones 
193986f309fdSLee Jones 	/* Set timing parameters */
194086f309fdSLee Jones 	writel(SPI_CFG_DEVICE_ST            |
194186f309fdSLee Jones 	       SPI_CFG_DEFAULT_MIN_CS_HIGH  |
194286f309fdSLee Jones 	       SPI_CFG_DEFAULT_CS_SETUPHOLD |
194386f309fdSLee Jones 	       SPI_CFG_DEFAULT_DATA_HOLD,
194486f309fdSLee Jones 	       fsm->base + SPI_CONFIGDATA);
194586f309fdSLee Jones 	writel(STFSM_DEFAULT_WR_TIME, fsm->base + SPI_STATUS_WR_TIME_REG);
194686f309fdSLee Jones 
194786f309fdSLee Jones 	/* Clear FIFO, just in case */
194886f309fdSLee Jones 	stfsm_clear_fifo(fsm);
194986f309fdSLee Jones 
195086f309fdSLee Jones 	return 0;
195186f309fdSLee Jones }
195286f309fdSLee Jones 
1953a63984c1SLee Jones static void stfsm_fetch_platform_configs(struct platform_device *pdev)
1954a63984c1SLee Jones {
1955a63984c1SLee Jones 	struct stfsm *fsm = platform_get_drvdata(pdev);
1956a63984c1SLee Jones 	struct device_node *np = pdev->dev.of_node;
1957a63984c1SLee Jones 	struct regmap *regmap;
1958a63984c1SLee Jones 	uint32_t boot_device_reg;
1959a63984c1SLee Jones 	uint32_t boot_device_spi;
1960a63984c1SLee Jones 	uint32_t boot_device;     /* Value we read from *boot_device_reg */
1961a63984c1SLee Jones 	int ret;
1962a63984c1SLee Jones 
1963a63984c1SLee Jones 	/* Booting from SPI NOR Flash is the default */
1964a63984c1SLee Jones 	fsm->booted_from_spi = true;
1965a63984c1SLee Jones 
1966a63984c1SLee Jones 	regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
1967a63984c1SLee Jones 	if (IS_ERR(regmap))
1968a63984c1SLee Jones 		goto boot_device_fail;
1969a63984c1SLee Jones 
19700ea7d706SLee Jones 	fsm->reset_signal = of_property_read_bool(np, "st,reset-signal");
19710ea7d706SLee Jones 
19720ea7d706SLee Jones 	fsm->reset_por = of_property_read_bool(np, "st,reset-por");
19730ea7d706SLee Jones 
1974a63984c1SLee Jones 	/* Where in the syscon the boot device information lives */
1975a63984c1SLee Jones 	ret = of_property_read_u32(np, "st,boot-device-reg", &boot_device_reg);
1976a63984c1SLee Jones 	if (ret)
1977a63984c1SLee Jones 		goto boot_device_fail;
1978a63984c1SLee Jones 
1979a63984c1SLee Jones 	/* Boot device value when booted from SPI NOR */
1980a63984c1SLee Jones 	ret = of_property_read_u32(np, "st,boot-device-spi", &boot_device_spi);
1981a63984c1SLee Jones 	if (ret)
1982a63984c1SLee Jones 		goto boot_device_fail;
1983a63984c1SLee Jones 
1984a63984c1SLee Jones 	ret = regmap_read(regmap, boot_device_reg, &boot_device);
1985a63984c1SLee Jones 	if (ret)
1986a63984c1SLee Jones 		goto boot_device_fail;
1987a63984c1SLee Jones 
1988a63984c1SLee Jones 	if (boot_device != boot_device_spi)
1989a63984c1SLee Jones 		fsm->booted_from_spi = false;
1990a63984c1SLee Jones 
1991a63984c1SLee Jones 	return;
1992a63984c1SLee Jones 
1993a63984c1SLee Jones boot_device_fail:
1994a63984c1SLee Jones 	dev_warn(&pdev->dev,
1995a63984c1SLee Jones 		 "failed to fetch boot device, assuming boot from SPI\n");
1996a63984c1SLee Jones }
1997a63984c1SLee Jones 
1998d90db4a0SLee Jones static int stfsm_probe(struct platform_device *pdev)
1999d90db4a0SLee Jones {
2000d90db4a0SLee Jones 	struct device_node *np = pdev->dev.of_node;
2001*221cff13SLee Jones 	struct mtd_part_parser_data ppdata;
200224fec651SLee Jones 	struct flash_info *info;
2003d90db4a0SLee Jones 	struct resource *res;
2004d90db4a0SLee Jones 	struct stfsm *fsm;
200586f309fdSLee Jones 	int ret;
2006d90db4a0SLee Jones 
2007d90db4a0SLee Jones 	if (!np) {
2008d90db4a0SLee Jones 		dev_err(&pdev->dev, "No DT found\n");
2009d90db4a0SLee Jones 		return -EINVAL;
2010d90db4a0SLee Jones 	}
2011*221cff13SLee Jones 	ppdata.of_node = np;
2012d90db4a0SLee Jones 
2013d90db4a0SLee Jones 	fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL);
2014d90db4a0SLee Jones 	if (!fsm)
2015d90db4a0SLee Jones 		return -ENOMEM;
2016d90db4a0SLee Jones 
2017d90db4a0SLee Jones 	fsm->dev = &pdev->dev;
2018d90db4a0SLee Jones 
2019d90db4a0SLee Jones 	platform_set_drvdata(pdev, fsm);
2020d90db4a0SLee Jones 
2021d90db4a0SLee Jones 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2022d90db4a0SLee Jones 	if (!res) {
2023d90db4a0SLee Jones 		dev_err(&pdev->dev, "Resource not found\n");
2024d90db4a0SLee Jones 		return -ENODEV;
2025d90db4a0SLee Jones 	}
2026d90db4a0SLee Jones 
2027d90db4a0SLee Jones 	fsm->base = devm_ioremap_resource(&pdev->dev, res);
2028d90db4a0SLee Jones 	if (IS_ERR(fsm->base)) {
2029d90db4a0SLee Jones 		dev_err(&pdev->dev,
2030d90db4a0SLee Jones 			"Failed to reserve memory region %pR\n", res);
2031d90db4a0SLee Jones 		return PTR_ERR(fsm->base);
2032d90db4a0SLee Jones 	}
2033d90db4a0SLee Jones 
2034d90db4a0SLee Jones 	mutex_init(&fsm->lock);
2035d90db4a0SLee Jones 
203686f309fdSLee Jones 	ret = stfsm_init(fsm);
203786f309fdSLee Jones 	if (ret) {
203886f309fdSLee Jones 		dev_err(&pdev->dev, "Failed to initialise FSM Controller\n");
203986f309fdSLee Jones 		return ret;
204086f309fdSLee Jones 	}
204186f309fdSLee Jones 
2042a63984c1SLee Jones 	stfsm_fetch_platform_configs(pdev);
2043a63984c1SLee Jones 
20441bd512b5SLee Jones 	/* Detect SPI FLASH device */
204524fec651SLee Jones 	info = stfsm_jedec_probe(fsm);
204624fec651SLee Jones 	if (!info)
204724fec651SLee Jones 		return -ENODEV;
204824fec651SLee Jones 	fsm->info = info;
20491bd512b5SLee Jones 
20503b5d1981SLee Jones 	/* Use device size to determine address width */
20513b5d1981SLee Jones 	if (info->sector_size * info->n_sectors > 0x1000000)
20523b5d1981SLee Jones 		info->flags |= FLASH_FLAG_32BIT_ADDR;
20533b5d1981SLee Jones 
2054218b870fSLee Jones 	/*
2055218b870fSLee Jones 	 * Configure READ/WRITE/ERASE sequences according to platform and
2056218b870fSLee Jones 	 * device flags.
2057218b870fSLee Jones 	 */
2058218b870fSLee Jones 	if (info->config) {
2059218b870fSLee Jones 		ret = info->config(fsm);
2060218b870fSLee Jones 		if (ret)
2061218b870fSLee Jones 			return ret;
20624eb3f0d8SLee Jones 	} else {
20634eb3f0d8SLee Jones 		ret = stfsm_prepare_rwe_seqs_default(fsm);
20644eb3f0d8SLee Jones 		if (ret)
20654eb3f0d8SLee Jones 			return ret;
2066218b870fSLee Jones 	}
2067218b870fSLee Jones 
2068*221cff13SLee Jones 	fsm->mtd.name		= info->name;
2069d90db4a0SLee Jones 	fsm->mtd.dev.parent	= &pdev->dev;
2070d90db4a0SLee Jones 	fsm->mtd.type		= MTD_NORFLASH;
2071d90db4a0SLee Jones 	fsm->mtd.writesize	= 4;
2072d90db4a0SLee Jones 	fsm->mtd.writebufsize	= fsm->mtd.writesize;
2073d90db4a0SLee Jones 	fsm->mtd.flags		= MTD_CAP_NORFLASH;
207424fec651SLee Jones 	fsm->mtd.size		= info->sector_size * info->n_sectors;
207524fec651SLee Jones 	fsm->mtd.erasesize	= info->sector_size;
207624fec651SLee Jones 
2077e514f105SLee Jones 	fsm->mtd._read  = stfsm_mtd_read;
2078176b4377SLee Jones 	fsm->mtd._write = stfsm_mtd_write;
20794a341fe7SLee Jones 	fsm->mtd._erase = stfsm_mtd_erase;
2080e514f105SLee Jones 
20814a341fe7SLee Jones 	dev_info(&pdev->dev,
208224fec651SLee Jones 		"Found serial flash device: %s\n"
208324fec651SLee Jones 		" size = %llx (%lldMiB) erasesize = 0x%08x (%uKiB)\n",
208424fec651SLee Jones 		info->name,
208524fec651SLee Jones 		(long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20),
208624fec651SLee Jones 		fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10));
2087d90db4a0SLee Jones 
2088*221cff13SLee Jones 	return mtd_device_parse_register(&fsm->mtd, NULL, &ppdata, NULL, 0);
2089d90db4a0SLee Jones }
2090d90db4a0SLee Jones 
2091d90db4a0SLee Jones static int stfsm_remove(struct platform_device *pdev)
2092d90db4a0SLee Jones {
2093d90db4a0SLee Jones 	struct stfsm *fsm = platform_get_drvdata(pdev);
2094d90db4a0SLee Jones 	int err;
2095d90db4a0SLee Jones 
2096d90db4a0SLee Jones 	err = mtd_device_unregister(&fsm->mtd);
2097d90db4a0SLee Jones 	if (err)
2098d90db4a0SLee Jones 		return err;
2099d90db4a0SLee Jones 
2100d90db4a0SLee Jones 	return 0;
2101d90db4a0SLee Jones }
2102d90db4a0SLee Jones 
2103d90db4a0SLee Jones static struct of_device_id stfsm_match[] = {
2104d90db4a0SLee Jones 	{ .compatible = "st,spi-fsm", },
2105d90db4a0SLee Jones 	{},
2106d90db4a0SLee Jones };
2107d90db4a0SLee Jones MODULE_DEVICE_TABLE(of, stfsm_match);
2108d90db4a0SLee Jones 
2109d90db4a0SLee Jones static struct platform_driver stfsm_driver = {
2110d90db4a0SLee Jones 	.probe		= stfsm_probe,
2111d90db4a0SLee Jones 	.remove		= stfsm_remove,
2112d90db4a0SLee Jones 	.driver		= {
2113d90db4a0SLee Jones 		.name	= "st-spi-fsm",
2114d90db4a0SLee Jones 		.owner	= THIS_MODULE,
2115d90db4a0SLee Jones 		.of_match_table = stfsm_match,
2116d90db4a0SLee Jones 	},
2117d90db4a0SLee Jones };
2118d90db4a0SLee Jones module_platform_driver(stfsm_driver);
2119d90db4a0SLee Jones 
2120d90db4a0SLee Jones MODULE_AUTHOR("Angus Clark <angus.clark@st.com>");
2121d90db4a0SLee Jones MODULE_DESCRIPTION("ST SPI FSM driver");
2122d90db4a0SLee Jones MODULE_LICENSE("GPL");
2123