blob: 20c644129654316ae52d7d01daa3f1d2c03d6d2e [file] [log] [blame]
Sheetal Tigadoliad0943e2019-12-18 19:44:43 +05301/*
2 * Copyright (c) 2016-2020, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <string.h>
8
9#include <common/debug.h>
10#include <lib/mmio.h>
11#include <sotp.h>
12
13#include <platform_def.h>
14#include <platform_sotp.h>
15
16#ifdef USE_SOFT_SOTP
17extern uint64_t soft_sotp[];
18#endif
19
20#define SOTP_PROG_CONTROL (SOTP_REGS_OTP_BASE + 0x0000)
21#define SOTP_PROG_CONTROL__OTP_CPU_MODE_EN 15
22#define SOTP_PROG_CONTROL__OTP_DISABLE_ECC 9
23#define SOTP_PROG_CONTROL__OTP_ECC_WREN 8
24
25#define SOTP_WRDATA_0 (SOTP_REGS_OTP_BASE + 0x0004)
26#define SOTP_WRDATA_1 (SOTP_REGS_OTP_BASE + 0x0008)
27
28#define SOTP_ADDR (SOTP_REGS_OTP_BASE + 0x000c)
29#define SOTP_ADDR__OTP_ROW_ADDR_R 6
30#define SOTP_ADDR_MASK 0x3FF
31
32#define SOTP_CTRL_0 (SOTP_REGS_OTP_BASE + 0x0010)
33#define SOTP_CTRL_0__START 0
34#define SOTP_CTRL_0__OTP_CMD 1
35
36#define SOTP_STATUS_0 (SOTP_REGS_OTP_BASE + 0x0018)
37#define SOTP_STATUS__FDONE 3
38
39#define SOTP_STATUS_1 (SOTP_REGS_OTP_BASE + 0x001c)
40#define SOTP_STATUS_1__CMD_DONE 1
41#define SOTP_STATUS_1__ECC_DET 17
42
43#define SOTP_RDDATA_0 (SOTP_REGS_OTP_BASE + 0x0020)
44#define SOTP_RDDATA_1 (SOTP_REGS_OTP_BASE + 0x0024)
45
46#define SOTP_READ 0
47
48#define SOTP_PROG_WORD 10
49#define SOTP_STATUS__PROGOK 2
50#define SOTP_PROG_ENABLE 2
51
52#define SOTP_ROW_DATA_MASK 0xffffffff
53#define SOTP_ECC_ERR_BITS_MASK 0x1ff00000000
54
55#define SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES 4
56#define SOTP_CHIP_CTRL_SW_MANU_PROG 5
57#define SOTP_CHIP_CTRL_SW_CID_PROG 6
58#define SOTP_CHIP_CTRL_SW_AB_DEVICE 8
59#define SOTP_CHIP_CTRL_SW_AB_DEV_MODE 9
60#define CHIP_STATE_UNPROGRAMMED 0x1
61#define CHIP_STATE_UNASSIGNED 0x2
62
63uint64_t sotp_mem_read(uint32_t offset, uint32_t sotp_add_ecc)
64{
65#ifdef USE_SOFT_SOTP
66 (void)sotp_add_ecc;
67
68 return soft_sotp[offset];
69#else
70 uint64_t read_data = 0;
71 uint64_t read_data1 = 0;
72 uint64_t read_data2 = 0;
73
74 /* Check for FDONE status */
75 while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) !=
76 BIT(SOTP_STATUS__FDONE))
77 ;
78
79 /* Enable OTP access by CPU */
80 mmio_setbits_32(SOTP_PROG_CONTROL,
81 BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN));
82
83 if (sotp_add_ecc == 1) {
84 mmio_clrbits_32(SOTP_PROG_CONTROL,
85 BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC));
86 }
87
88 if (sotp_add_ecc == 0) {
89 mmio_setbits_32(SOTP_PROG_CONTROL,
90 BIT(SOTP_PROG_CONTROL__OTP_DISABLE_ECC));
91 }
92
93 mmio_write_32(SOTP_ADDR,
94 ((offset & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R));
95 mmio_write_32(SOTP_CTRL_0, (SOTP_READ << SOTP_CTRL_0__OTP_CMD));
96
97 /* Start bit to tell SOTP to send command to the OTP controller */
98 mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START));
99
100 /* Wait for SOTP command done to be set */
101 while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) !=
102 BIT(SOTP_STATUS_1__CMD_DONE))
103 ;
104
105 /* Clr Start bit after command done */
106 mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START));
107
108 if ((offset > SOTP_DEVICE_SECURE_CFG3_ROW) &&
109 (mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__ECC_DET))) {
110 ERROR("SOTP ECC ERROR Detected row offset %d\n", offset);
111 read_data = SOTP_ECC_ERR_DETECT;
112 } else {
113 read_data1 = (uint64_t)mmio_read_32(SOTP_RDDATA_0);
114 read_data1 = read_data1 & 0xFFFFFFFF;
115 read_data2 = (uint64_t)mmio_read_32(SOTP_RDDATA_1);
116 read_data2 = (read_data2 & 0x1ff) << 32;
117 read_data = read_data1 | read_data2;
118 }
119
120 /* Command done is cleared */
121 mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE));
122
123 /* disable OTP access by CPU */
124 mmio_clrbits_32(SOTP_PROG_CONTROL,
125 BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN));
126
127 return read_data;
128#endif
129}
130
131void sotp_mem_write(uint32_t addr, uint32_t sotp_add_ecc, uint64_t wdata)
132{
133#ifdef USE_SOFT_SOTP
134 (void)sotp_add_ecc;
135
136 soft_sotp[addr] = wdata;
137#else
138 uint32_t loop;
139 uint8_t prog_array[4] = { 0x0F, 0x04, 0x08, 0x0D };
140
141 uint32_t chip_state_default =
142 (CHIP_STATE_UNASSIGNED|CHIP_STATE_UNPROGRAMMED);
143 uint32_t chip_state = mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES);
144 uint32_t chip_ctrl_default = 0;
145
146 /*
147 * The override settings is required to allow the customer to program
148 * the application specific keys into SOTP, before the conversion to
149 * one of the AB modes.
150 * At the end of write operation, the chip ctrl settings will restored
151 * to the state prior to write call
152 */
153 if (chip_state & chip_state_default) {
154 uint32_t chip_ctrl;
155
156 chip_ctrl_default = mmio_read_32(SOTP_CHIP_CTRL);
157 INFO("SOTP: enable special prog mode\n");
158
159 chip_ctrl = BIT(SOTP_CHIP_CTRL_SW_OVERRIDE_CHIP_STATES) |
160 BIT(SOTP_CHIP_CTRL_SW_MANU_PROG) |
161 BIT(SOTP_CHIP_CTRL_SW_CID_PROG) |
162 BIT(SOTP_CHIP_CTRL_SW_AB_DEVICE);
163 mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl);
164 }
165
166 /* Check for FDONE status */
167 while ((mmio_read_32(SOTP_STATUS_0) & BIT(SOTP_STATUS__FDONE)) !=
168 BIT(SOTP_STATUS__FDONE))
169 ;
170
Elyes Haouas2be03c02023-02-13 09:14:48 +0100171 /* Enable OTP access by CPU */
Sheetal Tigadoliad0943e2019-12-18 19:44:43 +0530172 mmio_setbits_32(SOTP_PROG_CONTROL,
173 BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN));
174
175 if (addr > SOTP_DEVICE_SECURE_CFG3_ROW) {
176 if (sotp_add_ecc == 0) {
177 mmio_clrbits_32(SOTP_PROG_CONTROL,
178 BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN));
179 }
180 if (sotp_add_ecc == 1) {
181 mmio_setbits_32(SOTP_PROG_CONTROL,
182 BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN));
183 }
184 } else {
185 mmio_clrbits_32(SOTP_PROG_CONTROL,
186 BIT(SOTP_PROG_CONTROL__OTP_ECC_WREN));
187 }
188
189 mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_ENABLE << 1));
190
191 /*
192 * In order to avoid unintentional writes / programming of the OTP
193 * array, the OTP Controller must be put into programming mode before
194 * it will accept program commands. This is done by writing 0xF, 0x4,
195 * 0x8, 0xD with program commands prior to starting the actual
196 * programming sequence
197 */
198 for (loop = 0; loop < 4; loop++) {
199 mmio_write_32(SOTP_WRDATA_0, prog_array[loop]);
200
201 /*
202 * Start bit to tell SOTP to send command to the OTP controller
203 */
204 mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START));
205
206 /* Wait for SOTP command done to <-- be set */
207 while ((mmio_read_32(SOTP_STATUS_1) &
208 BIT(SOTP_STATUS_1__CMD_DONE)) !=
209 BIT(SOTP_STATUS_1__CMD_DONE))
210 ;
211
212 /* Command done is cleared w1c */
213 mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE));
214
215 /* Clr Start bit after command done */
216 mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START));
217 }
218
219 /* Check for PROGOK */
220 while ((mmio_read_32(SOTP_STATUS_0) & 0x4) != BIT(SOTP_STATUS__PROGOK))
221 ;
222
223 /* Set 10 bit row address */
224 mmio_write_32(SOTP_ADDR,
225 ((addr & SOTP_ADDR_MASK) << SOTP_ADDR__OTP_ROW_ADDR_R));
226
227 /* Set SOTP Row data */
228 mmio_write_32(SOTP_WRDATA_0, (wdata & SOTP_ROW_DATA_MASK));
229
230 /* Set SOTP ECC and error bits */
231 mmio_write_32(SOTP_WRDATA_1, ((wdata & SOTP_ECC_ERR_BITS_MASK) >> 32));
232
233 /* Set prog_word command */
234 mmio_write_32(SOTP_CTRL_0, (SOTP_PROG_WORD << 1));
235
236 /* Start bit to tell SOTP to send command to the OTP controller */
237 mmio_setbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START));
238
239 /* Wait for SOTP command done to be set */
240 while ((mmio_read_32(SOTP_STATUS_1) & BIT(SOTP_STATUS_1__CMD_DONE)) !=
241 BIT(SOTP_STATUS_1__CMD_DONE))
242 ;
243
244 /* Command done is cleared w1c */
245 mmio_setbits_32(SOTP_STATUS_1, BIT(SOTP_STATUS_1__CMD_DONE));
246
Elyes Haouas2be03c02023-02-13 09:14:48 +0100247 /* disable OTP access by CPU */
Sheetal Tigadoliad0943e2019-12-18 19:44:43 +0530248 mmio_clrbits_32(SOTP_PROG_CONTROL,
249 BIT(SOTP_PROG_CONTROL__OTP_CPU_MODE_EN));
250
251 /* Clr Start bit after command done */
252 mmio_clrbits_32(SOTP_CTRL_0, BIT(SOTP_CTRL_0__START));
253
254 if (chip_state & chip_state_default)
255 mmio_write_32(SOTP_CHIP_CTRL, chip_ctrl_default);
256
257#endif
258}
259
260int sotp_read_key(uint8_t *key, size_t keysize, int start_row, int end_row)
261{
262 int row;
263 uint32_t status = 0;
264 uint32_t status2 = 0xFFFFFFFF;
265 uint64_t row_data;
266 uint32_t data;
267 uint32_t *temp_key = (uint32_t *)key;
268
269 row = start_row;
270 while ((keysize > 0) && (row <= end_row)) {
271 row_data = sotp_mem_read(row, SOTP_ROW_ECC);
272 if (!(row_data & (SOTP_ECC_ERR_DETECT | SOTP_FAIL_BITS))) {
273 memcpy(temp_key++, &row_data, sizeof(uint32_t));
274 keysize -= sizeof(uint32_t);
275 data = (uint32_t)(row_data & SOTP_ROW_DATA_MASK);
276 status |= data;
277 status2 &= data;
278 }
279 row++;
280 }
281
282 if ((status2 == 0xFFFFFFFF) || (status == 0) || (row > end_row))
283 return -1;
284
285 return 0;
286}
287
288int sotp_key_erased(void)
289{
290 uint64_t row_data;
291 int status = 0;
292
293 row_data = sotp_mem_read(SOTP_DEVICE_SECURE_CFG0_ROW, 0);
294 if (row_data & SOTP_DEVICE_SECURE_CFG0_OTP_ERASED_MASK)
295 status = 1;
296
297 else if (mmio_read_32(SOTP_REGS_SOTP_CHIP_STATES) &
298 SOTP_REGS_SOTP_CHIP_STATES_OTP_ERASED_MASK)
299 status = 1;
300
301 return status;
302}
303
304/*
305 * This function optimise the SOTP redundancy
306 * by considering the 00- zero and 01,10,11 - one
307 */
308uint32_t sotp_redundancy_reduction(uint32_t sotp_row_data)
309{
310 uint32_t opt_data;
311 uint32_t opt_loop;
312 uint32_t temp_data;
313
314 opt_data = 0;
315
316 for (opt_loop = 0; opt_loop < 16; opt_loop = opt_loop + 1) {
317 temp_data = ((sotp_row_data >> (opt_loop * 2)) & 0x3);
318
319 if (temp_data != 0x0)
320 opt_data = (opt_data | (1 << opt_loop));
321 }
322 return opt_data;
323}