1 /*
2  * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef DRIVERS_NAND_H
8 #define DRIVERS_NAND_H
9 
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include <lib/utils_def.h>
14 
15 #define PSEC_TO_MSEC(x)	div_round_up((x), 1000000000ULL)
16 
17 struct ecc {
18 	unsigned int mode; /* ECC mode NAND_ECC_MODE_{NONE|HW|ONDIE} */
19 	unsigned int size; /* Data byte per ECC step */
20 	unsigned int bytes; /* ECC bytes per step */
21 	unsigned int max_bit_corr; /* Max correctible bits per ECC steps */
22 };
23 
24 struct nand_device {
25 	unsigned int block_size;
26 	unsigned int page_size;
27 	unsigned long long size;
28 	unsigned int nb_planes;
29 	unsigned int buswidth;
30 	struct ecc ecc;
31 	int (*mtd_block_is_bad)(unsigned int block);
32 	int (*mtd_read_page)(struct nand_device *nand, unsigned int page,
33 			     uintptr_t buffer);
34 };
35 
36 /*
37  * Read bytes from NAND device
38  *
39  * @offset: Byte offset to read from in device
40  * @buffer: [out] Bytes read from device
41  * @length: Number of bytes to read
42  * @length_read: [out] Number of bytes read from device
43  * Return: 0 on success, a negative errno on failure
44  */
45 int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
46 	      size_t *length_read);
47 
48 /*
49  * Look for an extra offset to be added in case of bad blocks
50  *
51  * @base: Base address of the area
52  * @offset: Byte offset to read from in device
53  * @extra_offset: [out] Extra offset to be added if bad blocks are found
54  * Return: 0 on success, a negative errno on failure
55  */
56 int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset);
57 
58 /*
59  * Get NAND device instance
60  *
61  * Return: NAND device instance reference
62  */
63 struct nand_device *get_nand_device(void);
64 
65 #endif	/* DRIVERS_NAND_H */
66