1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * © Copyright 2016 ATMEL
4  * © Copyright 2016 Free Electrons
5  *
6  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
7  *
8  * Derived from the atmel_nand.c driver which contained the following
9  * copyrights:
10  *
11  *    Copyright © 2003 Rick Bronson
12  *
13  *    Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8)
14  *        Copyright © 2001 Thomas Gleixner (gleixner@autronix.de)
15  *
16  *    Derived from drivers/mtd/spia.c (removed in v3.8)
17  *        Copyright © 2000 Steven J. Hill (sjhill@cotw.com)
18  *
19  *
20  *    Add Hardware ECC support for AT91SAM9260 / AT91SAM9263
21  *        Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright © 2007
22  *
23  *        Derived from Das U-Boot source code
24  *              (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c)
25  *        © Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
26  *
27  *    Add Programmable Multibit ECC support for various AT91 SoC
28  *        © Copyright 2012 ATMEL, Hong Xu
29  *
30  *    Add Nand Flash Controller support for SAMA5 SoC
31  *        © Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com)
32  */
33 
34 #ifndef ATMEL_PMECC_H
35 #define ATMEL_PMECC_H
36 
37 #define ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH	0
38 #define ATMEL_PMECC_SECTOR_SIZE_AUTO		0
39 #define ATMEL_PMECC_OOBOFFSET_AUTO		-1
40 
41 struct atmel_pmecc_user_req {
42 	int pagesize;
43 	int oobsize;
44 	struct {
45 		int strength;
46 		int bytes;
47 		int sectorsize;
48 		int nsectors;
49 		int ooboffset;
50 	} ecc;
51 };
52 
53 struct atmel_pmecc_suspend_ctx {
54 	u32 setup;
55 	u32 pulse;
56 	u32 cycle;
57 	u32 timings;
58 	u32 mode;
59 };
60 
61 struct atmel_pmecc {
62 	struct udevice *dev;
63 	const struct atmel_pmecc_caps *caps;
64 
65 	struct {
66 		void __iomem *base;
67 		void __iomem *errloc;
68 		void __iomem *timing;
69 	} regs;
70 
71 	/* Mutex used for pmecc enable/disable */
72 	struct mutex lock;
73 
74 	struct atmel_pmecc_suspend_ctx suspend;
75 };
76 
77 struct atmel_pmecc *devm_atmel_pmecc_get(struct udevice *dev);
78 
79 struct atmel_pmecc_user *
80 atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
81 			struct atmel_pmecc_user_req *req);
82 void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
83 
84 void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
85 int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
86 void atmel_pmecc_disable(struct atmel_pmecc_user *user);
87 int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user);
88 int atmel_pmecc_correct_sector(struct atmel_pmecc_user *user, int sector,
89 			       void *data, void *ecc);
90 bool atmel_pmecc_correct_erased_chunks(struct atmel_pmecc_user *user);
91 void atmel_pmecc_get_generated_eccbytes(struct atmel_pmecc_user *user,
92 					int sector, void *ecc);
93 
94 #endif /* ATMEL_PMECC_H */
95