1 /*
2  * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <drivers/nand.h>
10 #include <drivers/raw_nand.h>
11 #include <drivers/spi_nand.h>
12 #include <drivers/spi_nor.h>
13 #include <lib/utils.h>
14 #include <plat/common/platform.h>
15 
16 #define SZ_512		0x200U
17 #define SZ_64M		0x4000000U
18 
19 #if STM32MP_RAW_NAND || STM32MP_SPI_NAND
get_data_from_otp(struct nand_device * nand_dev,bool is_slc)20 static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc)
21 {
22 	int result;
23 	uint32_t nand_param;
24 
25 	/* Check if NAND parameters are stored in OTP */
26 	result = bsec_shadow_read_otp(&nand_param, NAND_OTP);
27 	if (result != BSEC_OK) {
28 		ERROR("BSEC: NAND_OTP Error %i\n", result);
29 		return -EACCES;
30 	}
31 
32 	if (nand_param == 0U) {
33 		return 0;
34 	}
35 
36 	if ((nand_param & NAND_PARAM_STORED_IN_OTP) == 0U) {
37 		goto ecc;
38 	}
39 
40 	/* NAND parameter shall be read from OTP */
41 	if ((nand_param & NAND_WIDTH_MASK) != 0U) {
42 		nand_dev->buswidth = NAND_BUS_WIDTH_16;
43 	} else {
44 		nand_dev->buswidth = NAND_BUS_WIDTH_8;
45 	}
46 
47 	switch ((nand_param & NAND_PAGE_SIZE_MASK) >> NAND_PAGE_SIZE_SHIFT) {
48 	case NAND_PAGE_SIZE_2K:
49 		nand_dev->page_size = 0x800U;
50 		break;
51 
52 	case NAND_PAGE_SIZE_4K:
53 		nand_dev->page_size = 0x1000U;
54 		break;
55 
56 	case NAND_PAGE_SIZE_8K:
57 		nand_dev->page_size = 0x2000U;
58 		break;
59 
60 	default:
61 		ERROR("Cannot read NAND page size\n");
62 		return -EINVAL;
63 	}
64 
65 	switch ((nand_param & NAND_BLOCK_SIZE_MASK) >> NAND_BLOCK_SIZE_SHIFT) {
66 	case NAND_BLOCK_SIZE_64_PAGES:
67 		nand_dev->block_size = 64U * nand_dev->page_size;
68 		break;
69 
70 	case NAND_BLOCK_SIZE_128_PAGES:
71 		nand_dev->block_size = 128U * nand_dev->page_size;
72 		break;
73 
74 	case NAND_BLOCK_SIZE_256_PAGES:
75 		nand_dev->block_size = 256U * nand_dev->page_size;
76 		break;
77 
78 	default:
79 		ERROR("Cannot read NAND block size\n");
80 		return -EINVAL;
81 	}
82 
83 	nand_dev->size = ((nand_param & NAND_BLOCK_NB_MASK) >>
84 			  NAND_BLOCK_NB_SHIFT) *
85 		NAND_BLOCK_NB_UNIT * nand_dev->block_size;
86 
87 ecc:
88 	if (is_slc) {
89 		switch ((nand_param & NAND_ECC_BIT_NB_MASK) >>
90 			NAND_ECC_BIT_NB_SHIFT) {
91 		case NAND_ECC_BIT_NB_1_BITS:
92 			nand_dev->ecc.max_bit_corr = 1U;
93 			break;
94 
95 		case NAND_ECC_BIT_NB_4_BITS:
96 			nand_dev->ecc.max_bit_corr = 4U;
97 			break;
98 
99 		case NAND_ECC_BIT_NB_8_BITS:
100 			nand_dev->ecc.max_bit_corr = 8U;
101 			break;
102 
103 		case NAND_ECC_ON_DIE:
104 			nand_dev->ecc.mode = NAND_ECC_ONDIE;
105 			break;
106 
107 		default:
108 			if (nand_dev->ecc.max_bit_corr == 0U) {
109 				ERROR("No valid eccbit number\n");
110 				return -EINVAL;
111 			}
112 		}
113 	} else {
114 		/* Selected multiple plane NAND */
115 		if ((nand_param & NAND_PLANE_BIT_NB_MASK) != 0U) {
116 			nand_dev->nb_planes = 2U;
117 		} else {
118 			nand_dev->nb_planes = 1U;
119 		}
120 	}
121 
122 	VERBOSE("OTP: Block %i Page %i Size %lli\n", nand_dev->block_size,
123 	     nand_dev->page_size, nand_dev->size);
124 
125 	return 0;
126 }
127 #endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
128 
129 #if STM32MP_RAW_NAND
plat_get_raw_nand_data(struct rawnand_device * device)130 int plat_get_raw_nand_data(struct rawnand_device *device)
131 {
132 	device->nand_dev->ecc.mode = NAND_ECC_HW;
133 	device->nand_dev->ecc.size = SZ_512;
134 
135 	return get_data_from_otp(device->nand_dev, true);
136 }
137 #endif
138 
139 #if STM32MP_SPI_NAND
plat_get_spi_nand_data(struct spinand_device * device)140 int plat_get_spi_nand_data(struct spinand_device *device)
141 {
142 	zeromem(&device->spi_read_cache_op, sizeof(struct spi_mem_op));
143 	device->spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE_4X;
144 	device->spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
145 	device->spi_read_cache_op.addr.nbytes = 2U;
146 	device->spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
147 	device->spi_read_cache_op.dummy.nbytes = 1U;
148 	device->spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
149 	device->spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
150 	device->spi_read_cache_op.data.dir = SPI_MEM_DATA_IN;
151 
152 	return get_data_from_otp(device->nand_dev, false);
153 }
154 #endif
155 
156 #if STM32MP_SPI_NOR
plat_get_nor_data(struct nor_device * device)157 int plat_get_nor_data(struct nor_device *device)
158 {
159 	device->size = SZ_64M;
160 
161 	zeromem(&device->read_op, sizeof(struct spi_mem_op));
162 	device->read_op.cmd.opcode = SPI_NOR_OP_READ_1_1_4;
163 	device->read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
164 	device->read_op.addr.nbytes = 3U;
165 	device->read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
166 	device->read_op.dummy.nbytes = 1U;
167 	device->read_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
168 	device->read_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
169 	device->read_op.data.dir = SPI_MEM_DATA_IN;
170 
171 	return 0;
172 }
173 #endif
174