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
41struct 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
53struct atmel_pmecc_suspend_ctx {
54	u32 setup;
55	u32 pulse;
56	u32 cycle;
57	u32 timings;
58	u32 mode;
59};
60
61struct 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
77struct atmel_pmecc *devm_atmel_pmecc_get(struct udevice *dev);
78
79struct atmel_pmecc_user *
80atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
81			struct atmel_pmecc_user_req *req);
82void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
83
84void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
85int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
86void atmel_pmecc_disable(struct atmel_pmecc_user *user);
87int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user);
88int atmel_pmecc_correct_sector(struct atmel_pmecc_user *user, int sector,
89			       void *data, void *ecc);
90bool atmel_pmecc_correct_erased_chunks(struct atmel_pmecc_user *user);
91void atmel_pmecc_get_generated_eccbytes(struct atmel_pmecc_user *user,
92					int sector, void *ecc);
93
94#endif /* ATMEL_PMECC_H */
95