xref: /rk3399_rockchip-uboot/include/linux/mtd/spinand.h (revision 749af7cd07a192b94067ae11b805eed1fd5a26b6)
1*749af7cdSPeter Pan /* SPDX-License-Identifier: GPL-2.0 */
2*749af7cdSPeter Pan /*
3*749af7cdSPeter Pan  * Copyright (c) 2016-2017 Micron Technology, Inc.
4*749af7cdSPeter Pan  *
5*749af7cdSPeter Pan  *  Authors:
6*749af7cdSPeter Pan  *	Peter Pan <peterpandong@micron.com>
7*749af7cdSPeter Pan  */
8*749af7cdSPeter Pan #ifndef __LINUX_MTD_SPINAND_H
9*749af7cdSPeter Pan #define __LINUX_MTD_SPINAND_H
10*749af7cdSPeter Pan 
11*749af7cdSPeter Pan #ifndef __UBOOT__
12*749af7cdSPeter Pan #include <linux/mutex.h>
13*749af7cdSPeter Pan #include <linux/bitops.h>
14*749af7cdSPeter Pan #include <linux/device.h>
15*749af7cdSPeter Pan #include <linux/mtd/mtd.h>
16*749af7cdSPeter Pan #include <linux/mtd/nand.h>
17*749af7cdSPeter Pan #include <linux/spi/spi.h>
18*749af7cdSPeter Pan #include <linux/spi/spi-mem.h>
19*749af7cdSPeter Pan #else
20*749af7cdSPeter Pan #include <common.h>
21*749af7cdSPeter Pan #include <spi.h>
22*749af7cdSPeter Pan #include <spi-mem.h>
23*749af7cdSPeter Pan #include <linux/mtd/nand.h>
24*749af7cdSPeter Pan #endif
25*749af7cdSPeter Pan 
26*749af7cdSPeter Pan /**
27*749af7cdSPeter Pan  * Standard SPI NAND flash operations
28*749af7cdSPeter Pan  */
29*749af7cdSPeter Pan 
30*749af7cdSPeter Pan #define SPINAND_RESET_OP						\
31*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0xff, 1),				\
32*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_ADDR,					\
33*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
34*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DATA)
35*749af7cdSPeter Pan 
36*749af7cdSPeter Pan #define SPINAND_WR_EN_DIS_OP(enable)					\
37*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD((enable) ? 0x06 : 0x04, 1),		\
38*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_ADDR,					\
39*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
40*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DATA)
41*749af7cdSPeter Pan 
42*749af7cdSPeter Pan #define SPINAND_READID_OP(ndummy, buf, len)				\
43*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1),				\
44*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_ADDR,					\
45*749af7cdSPeter Pan 		   SPI_MEM_OP_DUMMY(ndummy, 1),				\
46*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(len, buf, 1))
47*749af7cdSPeter Pan 
48*749af7cdSPeter Pan #define SPINAND_SET_FEATURE_OP(reg, valptr)				\
49*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x1f, 1),				\
50*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(1, reg, 1),				\
51*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
52*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_OUT(1, valptr, 1))
53*749af7cdSPeter Pan 
54*749af7cdSPeter Pan #define SPINAND_GET_FEATURE_OP(reg, valptr)				\
55*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x0f, 1),				\
56*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(1, reg, 1),				\
57*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
58*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(1, valptr, 1))
59*749af7cdSPeter Pan 
60*749af7cdSPeter Pan #define SPINAND_BLK_ERASE_OP(addr)					\
61*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0xd8, 1),				\
62*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(3, addr, 1),				\
63*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
64*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DATA)
65*749af7cdSPeter Pan 
66*749af7cdSPeter Pan #define SPINAND_PAGE_READ_OP(addr)					\
67*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x13, 1),				\
68*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(3, addr, 1),				\
69*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
70*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DATA)
71*749af7cdSPeter Pan 
72*749af7cdSPeter Pan #define SPINAND_PAGE_READ_FROM_CACHE_OP(fast, addr, ndummy, buf, len)	\
73*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1),		\
74*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 1),				\
75*749af7cdSPeter Pan 		   SPI_MEM_OP_DUMMY(ndummy, 1),				\
76*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(len, buf, 1))
77*749af7cdSPeter Pan 
78*749af7cdSPeter Pan #define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len)	\
79*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1),				\
80*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 1),				\
81*749af7cdSPeter Pan 		   SPI_MEM_OP_DUMMY(ndummy, 1),				\
82*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(len, buf, 2))
83*749af7cdSPeter Pan 
84*749af7cdSPeter Pan #define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len)	\
85*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1),				\
86*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 1),				\
87*749af7cdSPeter Pan 		   SPI_MEM_OP_DUMMY(ndummy, 1),				\
88*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(len, buf, 4))
89*749af7cdSPeter Pan 
90*749af7cdSPeter Pan #define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len)	\
91*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1),				\
92*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 2),				\
93*749af7cdSPeter Pan 		   SPI_MEM_OP_DUMMY(ndummy, 2),				\
94*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(len, buf, 2))
95*749af7cdSPeter Pan 
96*749af7cdSPeter Pan #define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(addr, ndummy, buf, len)	\
97*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1),				\
98*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 4),				\
99*749af7cdSPeter Pan 		   SPI_MEM_OP_DUMMY(ndummy, 4),				\
100*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_IN(len, buf, 4))
101*749af7cdSPeter Pan 
102*749af7cdSPeter Pan #define SPINAND_PROG_EXEC_OP(addr)					\
103*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1),				\
104*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(3, addr, 1),				\
105*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
106*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DATA)
107*749af7cdSPeter Pan 
108*749af7cdSPeter Pan #define SPINAND_PROG_LOAD(reset, addr, buf, len)			\
109*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0x02 : 0x84, 1),		\
110*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 1),				\
111*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
112*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_OUT(len, buf, 1))
113*749af7cdSPeter Pan 
114*749af7cdSPeter Pan #define SPINAND_PROG_LOAD_X4(reset, addr, buf, len)			\
115*749af7cdSPeter Pan 	SPI_MEM_OP(SPI_MEM_OP_CMD(reset ? 0x32 : 0x34, 1),		\
116*749af7cdSPeter Pan 		   SPI_MEM_OP_ADDR(2, addr, 1),				\
117*749af7cdSPeter Pan 		   SPI_MEM_OP_NO_DUMMY,					\
118*749af7cdSPeter Pan 		   SPI_MEM_OP_DATA_OUT(len, buf, 4))
119*749af7cdSPeter Pan 
120*749af7cdSPeter Pan /**
121*749af7cdSPeter Pan  * Standard SPI NAND flash commands
122*749af7cdSPeter Pan  */
123*749af7cdSPeter Pan #define SPINAND_CMD_PROG_LOAD_X4		0x32
124*749af7cdSPeter Pan #define SPINAND_CMD_PROG_LOAD_RDM_DATA_X4	0x34
125*749af7cdSPeter Pan 
126*749af7cdSPeter Pan /* feature register */
127*749af7cdSPeter Pan #define REG_BLOCK_LOCK		0xa0
128*749af7cdSPeter Pan #define BL_ALL_UNLOCKED		0x00
129*749af7cdSPeter Pan 
130*749af7cdSPeter Pan /* configuration register */
131*749af7cdSPeter Pan #define REG_CFG			0xb0
132*749af7cdSPeter Pan #define CFG_OTP_ENABLE		BIT(6)
133*749af7cdSPeter Pan #define CFG_ECC_ENABLE		BIT(4)
134*749af7cdSPeter Pan #define CFG_QUAD_ENABLE		BIT(0)
135*749af7cdSPeter Pan 
136*749af7cdSPeter Pan /* status register */
137*749af7cdSPeter Pan #define REG_STATUS		0xc0
138*749af7cdSPeter Pan #define STATUS_BUSY		BIT(0)
139*749af7cdSPeter Pan #define STATUS_ERASE_FAILED	BIT(2)
140*749af7cdSPeter Pan #define STATUS_PROG_FAILED	BIT(3)
141*749af7cdSPeter Pan #define STATUS_ECC_MASK		GENMASK(5, 4)
142*749af7cdSPeter Pan #define STATUS_ECC_NO_BITFLIPS	(0 << 4)
143*749af7cdSPeter Pan #define STATUS_ECC_HAS_BITFLIPS	(1 << 4)
144*749af7cdSPeter Pan #define STATUS_ECC_UNCOR_ERROR	(2 << 4)
145*749af7cdSPeter Pan 
146*749af7cdSPeter Pan struct spinand_op;
147*749af7cdSPeter Pan struct spinand_device;
148*749af7cdSPeter Pan 
149*749af7cdSPeter Pan #define SPINAND_MAX_ID_LEN	4
150*749af7cdSPeter Pan 
151*749af7cdSPeter Pan /**
152*749af7cdSPeter Pan  * struct spinand_id - SPI NAND id structure
153*749af7cdSPeter Pan  * @data: buffer containing the id bytes. Currently 4 bytes large, but can
154*749af7cdSPeter Pan  *	  be extended if required
155*749af7cdSPeter Pan  * @len: ID length
156*749af7cdSPeter Pan  *
157*749af7cdSPeter Pan  * struct_spinand_id->data contains all bytes returned after a READ_ID command,
158*749af7cdSPeter Pan  * including dummy bytes if the chip does not emit ID bytes right after the
159*749af7cdSPeter Pan  * READ_ID command. The responsibility to extract real ID bytes is left to
160*749af7cdSPeter Pan  * struct_manufacurer_ops->detect().
161*749af7cdSPeter Pan  */
162*749af7cdSPeter Pan struct spinand_id {
163*749af7cdSPeter Pan 	u8 data[SPINAND_MAX_ID_LEN];
164*749af7cdSPeter Pan 	int len;
165*749af7cdSPeter Pan };
166*749af7cdSPeter Pan 
167*749af7cdSPeter Pan /**
168*749af7cdSPeter Pan  * struct manufacurer_ops - SPI NAND manufacturer specific operations
169*749af7cdSPeter Pan  * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed
170*749af7cdSPeter Pan  *	    the core calls the struct_manufacurer_ops->detect() hook of each
171*749af7cdSPeter Pan  *	    registered manufacturer until one of them return 1. Note that
172*749af7cdSPeter Pan  *	    the first thing to check in this hook is that the manufacturer ID
173*749af7cdSPeter Pan  *	    in struct_spinand_device->id matches the manufacturer whose
174*749af7cdSPeter Pan  *	    ->detect() hook has been called. Should return 1 if there's a
175*749af7cdSPeter Pan  *	    match, 0 if the manufacturer ID does not match and a negative
176*749af7cdSPeter Pan  *	    error code otherwise. When true is returned, the core assumes
177*749af7cdSPeter Pan  *	    that properties of the NAND chip (spinand->base.memorg and
178*749af7cdSPeter Pan  *	    spinand->base.eccreq) have been filled
179*749af7cdSPeter Pan  * @init: initialize a SPI NAND device
180*749af7cdSPeter Pan  * @cleanup: cleanup a SPI NAND device
181*749af7cdSPeter Pan  *
182*749af7cdSPeter Pan  * Each SPI NAND manufacturer driver should implement this interface so that
183*749af7cdSPeter Pan  * NAND chips coming from this vendor can be detected and initialized properly.
184*749af7cdSPeter Pan  */
185*749af7cdSPeter Pan struct spinand_manufacturer_ops {
186*749af7cdSPeter Pan 	int (*detect)(struct spinand_device *spinand);
187*749af7cdSPeter Pan 	int (*init)(struct spinand_device *spinand);
188*749af7cdSPeter Pan 	void (*cleanup)(struct spinand_device *spinand);
189*749af7cdSPeter Pan };
190*749af7cdSPeter Pan 
191*749af7cdSPeter Pan /**
192*749af7cdSPeter Pan  * struct spinand_manufacturer - SPI NAND manufacturer instance
193*749af7cdSPeter Pan  * @id: manufacturer ID
194*749af7cdSPeter Pan  * @name: manufacturer name
195*749af7cdSPeter Pan  * @ops: manufacturer operations
196*749af7cdSPeter Pan  */
197*749af7cdSPeter Pan struct spinand_manufacturer {
198*749af7cdSPeter Pan 	u8 id;
199*749af7cdSPeter Pan 	char *name;
200*749af7cdSPeter Pan 	const struct spinand_manufacturer_ops *ops;
201*749af7cdSPeter Pan };
202*749af7cdSPeter Pan 
203*749af7cdSPeter Pan /**
204*749af7cdSPeter Pan  * struct spinand_op_variants - SPI NAND operation variants
205*749af7cdSPeter Pan  * @ops: the list of variants for a given operation
206*749af7cdSPeter Pan  * @nops: the number of variants
207*749af7cdSPeter Pan  *
208*749af7cdSPeter Pan  * Some operations like read-from-cache/write-to-cache have several variants
209*749af7cdSPeter Pan  * depending on the number of IO lines you use to transfer data or address
210*749af7cdSPeter Pan  * cycles. This structure is a way to describe the different variants supported
211*749af7cdSPeter Pan  * by a chip and let the core pick the best one based on the SPI mem controller
212*749af7cdSPeter Pan  * capabilities.
213*749af7cdSPeter Pan  */
214*749af7cdSPeter Pan struct spinand_op_variants {
215*749af7cdSPeter Pan 	const struct spi_mem_op *ops;
216*749af7cdSPeter Pan 	unsigned int nops;
217*749af7cdSPeter Pan };
218*749af7cdSPeter Pan 
219*749af7cdSPeter Pan #define SPINAND_OP_VARIANTS(name, ...)					\
220*749af7cdSPeter Pan 	const struct spinand_op_variants name = {			\
221*749af7cdSPeter Pan 		.ops = (struct spi_mem_op[]) { __VA_ARGS__ },		\
222*749af7cdSPeter Pan 		.nops = sizeof((struct spi_mem_op[]){ __VA_ARGS__ }) /	\
223*749af7cdSPeter Pan 			sizeof(struct spi_mem_op),			\
224*749af7cdSPeter Pan 	}
225*749af7cdSPeter Pan 
226*749af7cdSPeter Pan /**
227*749af7cdSPeter Pan  * spinand_ecc_info - description of the on-die ECC implemented by a SPI NAND
228*749af7cdSPeter Pan  *		      chip
229*749af7cdSPeter Pan  * @get_status: get the ECC status. Should return a positive number encoding
230*749af7cdSPeter Pan  *		the number of corrected bitflips if correction was possible or
231*749af7cdSPeter Pan  *		-EBADMSG if there are uncorrectable errors. I can also return
232*749af7cdSPeter Pan  *		other negative error codes if the error is not caused by
233*749af7cdSPeter Pan  *		uncorrectable bitflips
234*749af7cdSPeter Pan  * @ooblayout: the OOB layout used by the on-die ECC implementation
235*749af7cdSPeter Pan  */
236*749af7cdSPeter Pan struct spinand_ecc_info {
237*749af7cdSPeter Pan 	int (*get_status)(struct spinand_device *spinand, u8 status);
238*749af7cdSPeter Pan 	const struct mtd_ooblayout_ops *ooblayout;
239*749af7cdSPeter Pan };
240*749af7cdSPeter Pan 
241*749af7cdSPeter Pan #define SPINAND_HAS_QE_BIT		BIT(0)
242*749af7cdSPeter Pan 
243*749af7cdSPeter Pan /**
244*749af7cdSPeter Pan  * struct spinand_info - Structure used to describe SPI NAND chips
245*749af7cdSPeter Pan  * @model: model name
246*749af7cdSPeter Pan  * @devid: device ID
247*749af7cdSPeter Pan  * @flags: OR-ing of the SPINAND_XXX flags
248*749af7cdSPeter Pan  * @memorg: memory organization
249*749af7cdSPeter Pan  * @eccreq: ECC requirements
250*749af7cdSPeter Pan  * @eccinfo: on-die ECC info
251*749af7cdSPeter Pan  * @op_variants: operations variants
252*749af7cdSPeter Pan  * @op_variants.read_cache: variants of the read-cache operation
253*749af7cdSPeter Pan  * @op_variants.write_cache: variants of the write-cache operation
254*749af7cdSPeter Pan  * @op_variants.update_cache: variants of the update-cache operation
255*749af7cdSPeter Pan  * @select_target: function used to select a target/die. Required only for
256*749af7cdSPeter Pan  *		   multi-die chips
257*749af7cdSPeter Pan  *
258*749af7cdSPeter Pan  * Each SPI NAND manufacturer driver should have a spinand_info table
259*749af7cdSPeter Pan  * describing all the chips supported by the driver.
260*749af7cdSPeter Pan  */
261*749af7cdSPeter Pan struct spinand_info {
262*749af7cdSPeter Pan 	const char *model;
263*749af7cdSPeter Pan 	u8 devid;
264*749af7cdSPeter Pan 	u32 flags;
265*749af7cdSPeter Pan 	struct nand_memory_organization memorg;
266*749af7cdSPeter Pan 	struct nand_ecc_req eccreq;
267*749af7cdSPeter Pan 	struct spinand_ecc_info eccinfo;
268*749af7cdSPeter Pan 	struct {
269*749af7cdSPeter Pan 		const struct spinand_op_variants *read_cache;
270*749af7cdSPeter Pan 		const struct spinand_op_variants *write_cache;
271*749af7cdSPeter Pan 		const struct spinand_op_variants *update_cache;
272*749af7cdSPeter Pan 	} op_variants;
273*749af7cdSPeter Pan 	int (*select_target)(struct spinand_device *spinand,
274*749af7cdSPeter Pan 			     unsigned int target);
275*749af7cdSPeter Pan };
276*749af7cdSPeter Pan 
277*749af7cdSPeter Pan #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update)		\
278*749af7cdSPeter Pan 	{								\
279*749af7cdSPeter Pan 		.read_cache = __read,					\
280*749af7cdSPeter Pan 		.write_cache = __write,					\
281*749af7cdSPeter Pan 		.update_cache = __update,				\
282*749af7cdSPeter Pan 	}
283*749af7cdSPeter Pan 
284*749af7cdSPeter Pan #define SPINAND_ECCINFO(__ooblayout, __get_status)			\
285*749af7cdSPeter Pan 	.eccinfo = {							\
286*749af7cdSPeter Pan 		.ooblayout = __ooblayout,				\
287*749af7cdSPeter Pan 		.get_status = __get_status,				\
288*749af7cdSPeter Pan 	}
289*749af7cdSPeter Pan 
290*749af7cdSPeter Pan #define SPINAND_SELECT_TARGET(__func)					\
291*749af7cdSPeter Pan 	.select_target = __func,
292*749af7cdSPeter Pan 
293*749af7cdSPeter Pan #define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants,	\
294*749af7cdSPeter Pan 		     __flags, ...)					\
295*749af7cdSPeter Pan 	{								\
296*749af7cdSPeter Pan 		.model = __model,					\
297*749af7cdSPeter Pan 		.devid = __id,						\
298*749af7cdSPeter Pan 		.memorg = __memorg,					\
299*749af7cdSPeter Pan 		.eccreq = __eccreq,					\
300*749af7cdSPeter Pan 		.op_variants = __op_variants,				\
301*749af7cdSPeter Pan 		.flags = __flags,					\
302*749af7cdSPeter Pan 		__VA_ARGS__						\
303*749af7cdSPeter Pan 	}
304*749af7cdSPeter Pan 
305*749af7cdSPeter Pan /**
306*749af7cdSPeter Pan  * struct spinand_device - SPI NAND device instance
307*749af7cdSPeter Pan  * @base: NAND device instance
308*749af7cdSPeter Pan  * @slave: pointer to the SPI slave object
309*749af7cdSPeter Pan  * @lock: lock used to serialize accesses to the NAND
310*749af7cdSPeter Pan  * @id: NAND ID as returned by READ_ID
311*749af7cdSPeter Pan  * @flags: NAND flags
312*749af7cdSPeter Pan  * @op_templates: various SPI mem op templates
313*749af7cdSPeter Pan  * @op_templates.read_cache: read cache op template
314*749af7cdSPeter Pan  * @op_templates.write_cache: write cache op template
315*749af7cdSPeter Pan  * @op_templates.update_cache: update cache op template
316*749af7cdSPeter Pan  * @select_target: select a specific target/die. Usually called before sending
317*749af7cdSPeter Pan  *		   a command addressing a page or an eraseblock embedded in
318*749af7cdSPeter Pan  *		   this die. Only required if your chip exposes several dies
319*749af7cdSPeter Pan  * @cur_target: currently selected target/die
320*749af7cdSPeter Pan  * @eccinfo: on-die ECC information
321*749af7cdSPeter Pan  * @cfg_cache: config register cache. One entry per die
322*749af7cdSPeter Pan  * @databuf: bounce buffer for data
323*749af7cdSPeter Pan  * @oobbuf: bounce buffer for OOB data
324*749af7cdSPeter Pan  * @scratchbuf: buffer used for everything but page accesses. This is needed
325*749af7cdSPeter Pan  *		because the spi-mem interface explicitly requests that buffers
326*749af7cdSPeter Pan  *		passed in spi_mem_op be DMA-able, so we can't based the bufs on
327*749af7cdSPeter Pan  *		the stack
328*749af7cdSPeter Pan  * @manufacturer: SPI NAND manufacturer information
329*749af7cdSPeter Pan  * @priv: manufacturer private data
330*749af7cdSPeter Pan  */
331*749af7cdSPeter Pan struct spinand_device {
332*749af7cdSPeter Pan 	struct nand_device base;
333*749af7cdSPeter Pan #ifndef __UBOOT__
334*749af7cdSPeter Pan 	struct spi_mem *spimem;
335*749af7cdSPeter Pan 	struct mutex lock;
336*749af7cdSPeter Pan #else
337*749af7cdSPeter Pan 	struct spi_slave *slave;
338*749af7cdSPeter Pan #endif
339*749af7cdSPeter Pan 	struct spinand_id id;
340*749af7cdSPeter Pan 	u32 flags;
341*749af7cdSPeter Pan 
342*749af7cdSPeter Pan 	struct {
343*749af7cdSPeter Pan 		const struct spi_mem_op *read_cache;
344*749af7cdSPeter Pan 		const struct spi_mem_op *write_cache;
345*749af7cdSPeter Pan 		const struct spi_mem_op *update_cache;
346*749af7cdSPeter Pan 	} op_templates;
347*749af7cdSPeter Pan 
348*749af7cdSPeter Pan 	int (*select_target)(struct spinand_device *spinand,
349*749af7cdSPeter Pan 			     unsigned int target);
350*749af7cdSPeter Pan 	unsigned int cur_target;
351*749af7cdSPeter Pan 
352*749af7cdSPeter Pan 	struct spinand_ecc_info eccinfo;
353*749af7cdSPeter Pan 
354*749af7cdSPeter Pan 	u8 *cfg_cache;
355*749af7cdSPeter Pan 	u8 *databuf;
356*749af7cdSPeter Pan 	u8 *oobbuf;
357*749af7cdSPeter Pan 	u8 *scratchbuf;
358*749af7cdSPeter Pan 	const struct spinand_manufacturer *manufacturer;
359*749af7cdSPeter Pan 	void *priv;
360*749af7cdSPeter Pan };
361*749af7cdSPeter Pan 
362*749af7cdSPeter Pan /**
363*749af7cdSPeter Pan  * mtd_to_spinand() - Get the SPI NAND device attached to an MTD instance
364*749af7cdSPeter Pan  * @mtd: MTD instance
365*749af7cdSPeter Pan  *
366*749af7cdSPeter Pan  * Return: the SPI NAND device attached to @mtd.
367*749af7cdSPeter Pan  */
368*749af7cdSPeter Pan static inline struct spinand_device *mtd_to_spinand(struct mtd_info *mtd)
369*749af7cdSPeter Pan {
370*749af7cdSPeter Pan 	return container_of(mtd_to_nanddev(mtd), struct spinand_device, base);
371*749af7cdSPeter Pan }
372*749af7cdSPeter Pan 
373*749af7cdSPeter Pan /**
374*749af7cdSPeter Pan  * spinand_to_mtd() - Get the MTD device embedded in a SPI NAND device
375*749af7cdSPeter Pan  * @spinand: SPI NAND device
376*749af7cdSPeter Pan  *
377*749af7cdSPeter Pan  * Return: the MTD device embedded in @spinand.
378*749af7cdSPeter Pan  */
379*749af7cdSPeter Pan static inline struct mtd_info *spinand_to_mtd(struct spinand_device *spinand)
380*749af7cdSPeter Pan {
381*749af7cdSPeter Pan 	return nanddev_to_mtd(&spinand->base);
382*749af7cdSPeter Pan }
383*749af7cdSPeter Pan 
384*749af7cdSPeter Pan /**
385*749af7cdSPeter Pan  * nand_to_spinand() - Get the SPI NAND device embedding an NAND object
386*749af7cdSPeter Pan  * @nand: NAND object
387*749af7cdSPeter Pan  *
388*749af7cdSPeter Pan  * Return: the SPI NAND device embedding @nand.
389*749af7cdSPeter Pan  */
390*749af7cdSPeter Pan static inline struct spinand_device *nand_to_spinand(struct nand_device *nand)
391*749af7cdSPeter Pan {
392*749af7cdSPeter Pan 	return container_of(nand, struct spinand_device, base);
393*749af7cdSPeter Pan }
394*749af7cdSPeter Pan 
395*749af7cdSPeter Pan /**
396*749af7cdSPeter Pan  * spinand_to_nand() - Get the NAND device embedded in a SPI NAND object
397*749af7cdSPeter Pan  * @spinand: SPI NAND device
398*749af7cdSPeter Pan  *
399*749af7cdSPeter Pan  * Return: the NAND device embedded in @spinand.
400*749af7cdSPeter Pan  */
401*749af7cdSPeter Pan static inline struct nand_device *
402*749af7cdSPeter Pan spinand_to_nand(struct spinand_device *spinand)
403*749af7cdSPeter Pan {
404*749af7cdSPeter Pan 	return &spinand->base;
405*749af7cdSPeter Pan }
406*749af7cdSPeter Pan 
407*749af7cdSPeter Pan /**
408*749af7cdSPeter Pan  * spinand_set_of_node - Attach a DT node to a SPI NAND device
409*749af7cdSPeter Pan  * @spinand: SPI NAND device
410*749af7cdSPeter Pan  * @np: DT node
411*749af7cdSPeter Pan  *
412*749af7cdSPeter Pan  * Attach a DT node to a SPI NAND device.
413*749af7cdSPeter Pan  */
414*749af7cdSPeter Pan static inline void spinand_set_of_node(struct spinand_device *spinand,
415*749af7cdSPeter Pan 				       const struct device_node *np)
416*749af7cdSPeter Pan {
417*749af7cdSPeter Pan 	nanddev_set_of_node(&spinand->base, np);
418*749af7cdSPeter Pan }
419*749af7cdSPeter Pan 
420*749af7cdSPeter Pan int spinand_match_and_init(struct spinand_device *dev,
421*749af7cdSPeter Pan 			   const struct spinand_info *table,
422*749af7cdSPeter Pan 			   unsigned int table_size, u8 devid);
423*749af7cdSPeter Pan 
424*749af7cdSPeter Pan int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
425*749af7cdSPeter Pan int spinand_select_target(struct spinand_device *spinand, unsigned int target);
426*749af7cdSPeter Pan 
427*749af7cdSPeter Pan #endif /* __LINUX_MTD_SPINAND_H */
428