1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2021 Nuvoton Technology Corp.
4 */
5
6 #include <clk.h>
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <fuse.h>
11 #include <asm/io.h>
12 #include <linux/delay.h>
13 #include <asm/arch/otp.h>
14
15 struct npcm_otp_priv {
16 struct npcm_otp_regs *regs[2];
17 };
18
19 static struct npcm_otp_priv *otp_priv;
20
21 /*----------------------------------------------------------------------------*/
22 /* Function: npcm_otp_check_inputs */
23 /* */
24 /* Parameters: arr - fuse array number to check */
25 /* word - fuse word (offset) to check */
26 /* Returns: int */
27 /* Side effects: */
28 /* Description: Checks is arr and word are illegal and do not exceed */
29 /* their range. Return 0 if they are legal, -1 if not */
30 /*----------------------------------------------------------------------------*/
npcm_otp_check_inputs(u32 arr,u32 word)31 static int npcm_otp_check_inputs(u32 arr, u32 word)
32 {
33 if (arr >= NPCM_NUM_OF_SA) {
34 if (IS_ENABLED(CONFIG_ARCH_NPCM8XX))
35 printf("\nError: npcm8XX otp includs only one bank: 0\n");
36 if (IS_ENABLED(CONFIG_ARCH_NPCM7XX))
37 printf("\nError: npcm7XX otp includs only two banks: 0 and 1\n");
38 return -1;
39 }
40
41 if (word >= NPCM_OTP_ARR_BYTE_SIZE) {
42 printf("\nError: npcm otp array comprises only %d bytes, numbered from 0 to %d\n",
43 NPCM_OTP_ARR_BYTE_SIZE, NPCM_OTP_ARR_BYTE_SIZE - 1);
44 return -1;
45 }
46
47 return 0;
48 }
49
50 /*----------------------------------------------------------------------------*/
51 /* Function: npcm_otp_wait_for_otp_ready */
52 /* */
53 /* Parameters: array - fuse array to wait for */
54 /* Returns: int */
55 /* Side effects: */
56 /* Description: Initialize the Fuse HW module. */
57 /*----------------------------------------------------------------------------*/
npcm_otp_wait_for_otp_ready(u32 arr,u32 timeout)58 static int npcm_otp_wait_for_otp_ready(u32 arr, u32 timeout)
59 {
60 struct npcm_otp_regs *regs = otp_priv->regs[arr];
61 u32 time = timeout;
62
63 /*------------------------------------------------------------------------*/
64 /* check parameters validity */
65 /*------------------------------------------------------------------------*/
66 if (arr > NPCM_FUSE_SA)
67 return -EINVAL;
68
69 while (--time > 1) {
70 if (readl(®s->fst) & FST_RDY) {
71 /* fuse is ready, clear the status. */
72 writel(readl(®s->fst) | FST_RDST, ®s->fst);
73 return 0;
74 }
75 }
76
77 /* try to clear the status in case it was set */
78 writel(readl(®s->fst) | FST_RDST, ®s->fst);
79
80 return -EINVAL;
81 }
82
83 /*----------------------------------------------------------------------------*/
84 /* Function: npcm_otp_read_byte */
85 /* */
86 /* Parameters: arr - Storage Array type [input]. */
87 /* addr - Byte-address to read from [input]. */
88 /* data - Pointer to result [output]. */
89 /* Returns: none */
90 /* Side effects: */
91 /* Description: Read 8-bit data from an OTP storage array. */
92 /*----------------------------------------------------------------------------*/
npcm_otp_read_byte(u32 arr,u32 addr,u8 * data)93 static void npcm_otp_read_byte(u32 arr, u32 addr, u8 *data)
94 {
95 struct npcm_otp_regs *regs = otp_priv->regs[arr];
96
97 /* Wait for the Fuse Box Idle */
98 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
99
100 /* Configure the byte address in the fuse array for read operation */
101 writel(FADDR_VAL(addr, 0), ®s->faddr);
102
103 /* Initiate a read cycle */
104 writel(READ_INIT, ®s->fctl);
105
106 /* Wait for read operation completion */
107 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
108
109 /* Read the result */
110 *data = readl(®s->fdata) & FDATA_MASK;
111
112 /* Clean FDATA contents to prevent unauthorized software from reading
113 * sensitive information
114 */
115 writel(FDATA_CLEAN_VALUE, ®s->fdata);
116 }
117
118 /*----------------------------------------------------------------------------*/
119 /* Function: npcm_otp_bit_is_programmed */
120 /* */
121 /* Parameters: arr - Storage Array type [input]. */
122 /* byte_offset - Byte offset in array [input]. */
123 /* bit_offset - Bit offset in byte [input]. */
124 /* Returns: Nonzero if bit is programmed, zero otherwise. */
125 /* Side effects: */
126 /* Description: Check if a bit is programmed in an OTP storage array. */
127 /*----------------------------------------------------------------------------*/
npcm_otp_bit_is_programmed(u32 arr,u32 byte_offset,u8 bit_offset)128 static bool npcm_otp_bit_is_programmed(u32 arr,
129 u32 byte_offset, u8 bit_offset)
130 {
131 u32 data = 0;
132
133 /* Read the entire byte you wish to program */
134 npcm_otp_read_byte(arr, byte_offset, (u8 *)&data);
135
136 /* Check whether the bit is already programmed */
137 if (data & (1 << bit_offset))
138 return true;
139
140 return false;
141 }
142
143 /*----------------------------------------------------------------------------*/
144 /* Function: npcm_otp_program_bit */
145 /* */
146 /* Parameters: arr - Storage Array type [input]. */
147 /* byte)offset - Byte offset in array [input]. */
148 /* bit_offset - Bit offset in byte [input]. */
149 /* Returns: int */
150 /* Side effects: */
151 /* Description: Program (set to 1) a bit in an OTP storage array. */
152 /*----------------------------------------------------------------------------*/
npcm_otp_program_bit(u32 arr,u32 byte_offset,u8 bit_offset)153 static int npcm_otp_program_bit(u32 arr, u32 byte_offset,
154 u8 bit_offset)
155 {
156 struct npcm_otp_regs *regs = otp_priv->regs[arr];
157 int count;
158 u8 read_data;
159
160 /* Wait for the Fuse Box Idle */
161 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
162
163 /* Make sure the bit is not already programmed */
164 if (npcm_otp_bit_is_programmed(arr, byte_offset, bit_offset))
165 return 0;
166
167 /* Configure the bit address in the fuse array for program operation */
168 writel(FADDR_VAL(byte_offset, bit_offset), ®s->faddr);
169 writel(readl(®s->faddr) | FADDR_IN_PROG, ®s->faddr);
170
171 // program up to MAX_PROGRAM_PULSES
172 for (count = 1; count <= MAX_PROGRAM_PULSES; count++) {
173 /* Initiate a program cycle */
174 writel(PROGRAM_ARM, ®s->fctl);
175 writel(PROGRAM_INIT, ®s->fctl);
176
177 /* Wait for program operation completion */
178 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
179
180 // after MIN_PROGRAM_PULSES start verifying the result
181 if (count >= MIN_PROGRAM_PULSES) {
182 /* Initiate a read cycle */
183 writel(READ_INIT, ®s->fctl);
184
185 /* Wait for read operation completion */
186 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
187
188 /* Read the result */
189 read_data = readl(®s->fdata) & FDATA_MASK;
190
191 /* If the bit is set the sequence ended correctly */
192 if (read_data & (1 << bit_offset))
193 break;
194 }
195 }
196
197 // check if programmking failed
198 if (count > MAX_PROGRAM_PULSES) {
199 printf("program fail\n");
200 return -EINVAL;
201 }
202
203 /*
204 * Clean FDATA contents to prevent unauthorized software from reading
205 * sensitive information
206 */
207 writel(FDATA_CLEAN_VALUE, ®s->fdata);
208
209 return 0;
210 }
211
212 /*----------------------------------------------------------------------------*/
213 /* Function: npcm_otp_program_byte */
214 /* */
215 /* Parameters: arr - Storage Array type [input]. */
216 /* byte_offset - Byte offset in array [input]. */
217 /* value - Byte to program [input]. */
218 /* Returns: int */
219 /* Side effects: */
220 /* Description: Program (set to 1) a given byte's relevant bits in an */
221 /* OTP storage array. */
222 /*----------------------------------------------------------------------------*/
npcm_otp_program_byte(u32 arr,u32 byte_offset,u8 value)223 static int npcm_otp_program_byte(u32 arr, u32 byte_offset,
224 u8 value)
225 {
226 int status = 0;
227 unsigned int i;
228 u8 data = 0;
229 int rc;
230
231 rc = npcm_otp_check_inputs(arr, byte_offset);
232 if (rc != 0)
233 return rc;
234
235 /* Wait for the Fuse Box Idle */
236 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
237
238 /* Read the entire byte you wish to program */
239 npcm_otp_read_byte(arr, byte_offset, &data);
240
241 /* In case all relevant bits are already programmed - nothing to do */
242 if ((~data & value) == 0)
243 return status;
244
245 /* Program unprogrammed bits. */
246 for (i = 0; i < 8; i++) {
247 if (value & (1 << i)) {
248 /* Program (set to 1) the relevant bit */
249 int last_status = npcm_otp_program_bit(arr, byte_offset, (u8)i);
250
251 if (last_status != 0)
252 status = last_status;
253 }
254 }
255 return status;
256 }
257
258 /*----------------------------------------------------------------------------*/
259 /* Function: npcm_otp_is_fuse_array_disabled */
260 /* */
261 /* Parameters: arr - Storage Array type [input]. */
262 /* Returns: bool */
263 /* Side effects: */
264 /* Description: Return true if access to the first 2048 bits of the */
265 /* specified fuse array is disabled, false if not */
266 /*----------------------------------------------------------------------------*/
npcm_otp_is_fuse_array_disabled(u32 arr)267 bool npcm_otp_is_fuse_array_disabled(u32 arr)
268 {
269 struct npcm_otp_regs *regs = otp_priv->regs[arr];
270
271 return (readl(®s->fcfg) & FCFG_FDIS) != 0;
272 }
273
npcm_otp_select_key(u8 key_index)274 int npcm_otp_select_key(u8 key_index)
275 {
276 struct npcm_otp_regs *regs = otp_priv->regs[NPCM_KEY_SA];
277 u32 idx = 0;
278 u32 time = 0xDAEDBEEF;
279
280 if (key_index >= 4)
281 return -1;
282
283 /* Do not destroy ECCDIS bit */
284 idx = readl(®s->fustrap_fkeyind);
285
286 /* Configure the key size */
287 idx &= ~FKEYIND_KSIZE_MASK;
288 idx |= FKEYIND_KSIZE_256;
289
290 /* Configure the key index (0 to 3) */
291 idx &= ~FKEYIND_KIND_MASK;
292 idx |= FKEYIND_KIND_KEY(key_index);
293
294 writel(idx, ®s->fustrap_fkeyind);
295
296 /* Wait for selection completetion */
297 while (--time > 1) {
298 if (readl(®s->fustrap_fkeyind) & FKEYIND_KVAL)
299 return 0;
300 udelay(1);
301 }
302
303 return -1;
304 }
305
306 /*----------------------------------------------------------------------------*/
307 /* Function: npcm_otp_nibble_parity_ecc_encode */
308 /* */
309 /* Parameters: datain - pointer to decoded data buffer */
310 /* dataout - pointer to encoded data buffer (buffer size */
311 /* should be 2 x dataout) */
312 /* size - size of encoded data (decoded data x 2) */
313 /* Returns: none */
314 /* Side effects: */
315 /* Description: Decodes the data according to nibble parity ECC scheme. */
316 /* Size specifies the encoded data size. */
317 /* Decodes whole bytes only */
318 /*----------------------------------------------------------------------------*/
npcm_otp_nibble_parity_ecc_encode(u8 * datain,u8 * dataout,u32 size)319 void npcm_otp_nibble_parity_ecc_encode(u8 *datain, u8 *dataout, u32 size)
320 {
321 u32 i, idx;
322 u8 E0, E1, E2, E3;
323
324 for (i = 0; i < (size / 2); i++) {
325 E0 = (datain[i] >> 0) & 0x01;
326 E1 = (datain[i] >> 1) & 0x01;
327 E2 = (datain[i] >> 2) & 0x01;
328 E3 = (datain[i] >> 3) & 0x01;
329
330 idx = i * 2;
331 dataout[idx] = datain[i] & 0x0f;
332 dataout[idx] |= (E0 ^ E1) << 4;
333 dataout[idx] |= (E2 ^ E3) << 5;
334 dataout[idx] |= (E0 ^ E2) << 6;
335 dataout[idx] |= (E1 ^ E3) << 7;
336
337 E0 = (datain[i] >> 4) & 0x01;
338 E1 = (datain[i] >> 5) & 0x01;
339 E2 = (datain[i] >> 6) & 0x01;
340 E3 = (datain[i] >> 7) & 0x01;
341
342 idx = i * 2 + 1;
343 dataout[idx] = (datain[i] & 0xf0) >> 4;
344 dataout[idx] |= (E0 ^ E1) << 4;
345 dataout[idx] |= (E2 ^ E3) << 5;
346 dataout[idx] |= (E0 ^ E2) << 6;
347 dataout[idx] |= (E1 ^ E3) << 7;
348 }
349 }
350
351 /*----------------------------------------------------------------------------*/
352 /* Function: npcm_otp_majority_rule_ecc_encode */
353 /* */
354 /* Parameters: datain - pointer to decoded data buffer */
355 /* dataout - pointer to encoded data buffer (buffer size */
356 /* should be 3 x dataout) */
357 /* size - size of encoded data (decoded data x 3) */
358 /* Returns: none */
359 /* Side effects: */
360 /* Description: Decodes the data according to Major Rule ECC scheme. */
361 /* Size specifies the encoded data size. */
362 /* Decodes whole bytes only */
363 /*----------------------------------------------------------------------------*/
npcm_otp_majority_rule_ecc_encode(u8 * datain,u8 * dataout,u32 size)364 void npcm_otp_majority_rule_ecc_encode(u8 *datain, u8 *dataout, u32 size)
365 {
366 u32 byte;
367 u32 bit;
368 u8 bit_val;
369 u32 decoded_size = size / 3;
370
371 for (byte = 0; byte < decoded_size; byte++) {
372 for (bit = 0; bit < 8; bit++) {
373 bit_val = (datain[byte] >> bit) & 0x01;
374
375 if (bit_val) {
376 dataout[byte] |= (1 << bit);
377 dataout[decoded_size + byte] |= (1 << bit);
378 dataout[decoded_size * 2 + byte] |= (1 << bit);
379 } else {
380 dataout[byte] &= ~(1 << bit);
381 dataout[decoded_size + byte] &= ~(1 << bit);
382 dataout[decoded_size * 2 + byte] &= ~(1 << bit);
383 }
384 }
385 }
386 }
387
388 /*----------------------------------------------------------------------------*/
389 /* Function: fuse_program_data */
390 /* */
391 /* Parameters: bank - Storage Array type [input]. */
392 /* word - Byte offset in array [input]. */
393 /* data - Pointer to data buffer to program. */
394 /* size - Number of bytes to program. */
395 /* Returns: none */
396 /* Side effects: */
397 /* Description: Programs the given byte array (size bytes) to the given */
398 /* OTP storage array, starting from offset word. */
399 /*----------------------------------------------------------------------------*/
fuse_program_data(u32 bank,u32 word,u8 * data,u32 size)400 int fuse_program_data(u32 bank, u32 word, u8 *data, u32 size)
401 {
402 u32 arr = (u32)bank;
403 u32 byte;
404 int rc;
405
406 rc = npcm_otp_check_inputs(bank, word + size - 1);
407 if (rc != 0)
408 return rc;
409
410 for (byte = 0; byte < size; byte++) {
411 u8 val;
412
413 val = data[byte];
414 if (val == 0) // optimization
415 continue;
416
417 rc = npcm_otp_program_byte(arr, word + byte, data[byte]);
418 if (rc != 0)
419 return rc;
420
421 // verify programming of every '1' bit
422 val = 0;
423 npcm_otp_read_byte((u32)bank, byte, &val);
424 if ((data[byte] & ~val) != 0)
425 return -1;
426 }
427
428 return 0;
429 }
430
fuse_prog_image(u32 bank,uintptr_t address)431 int fuse_prog_image(u32 bank, uintptr_t address)
432 {
433 return fuse_program_data(bank, 0, (u8 *)address, NPCM_OTP_ARR_BYTE_SIZE);
434 }
435
fuse_read(u32 bank,u32 word,u32 * val)436 int fuse_read(u32 bank, u32 word, u32 *val)
437 {
438 int rc = npcm_otp_check_inputs(bank, word);
439
440 if (rc != 0)
441 return rc;
442
443 *val = 0;
444 npcm_otp_read_byte((u32)bank, word, (u8 *)val);
445
446 return 0;
447 }
448
fuse_sense(u32 bank,u32 word,u32 * val)449 int fuse_sense(u32 bank, u32 word, u32 *val)
450 {
451 /* We do not support overriding */
452 return -EINVAL;
453 }
454
fuse_prog(u32 bank,u32 word,u32 val)455 int fuse_prog(u32 bank, u32 word, u32 val)
456 {
457 int rc;
458
459 rc = npcm_otp_check_inputs(bank, word);
460 if (rc != 0)
461 return rc;
462
463 return npcm_otp_program_byte(bank, word, (u8)val);
464 }
465
fuse_override(u32 bank,u32 word,u32 val)466 int fuse_override(u32 bank, u32 word, u32 val)
467 {
468 /* We do not support overriding */
469 return -EINVAL;
470 }
471
npcm_otp_bind(struct udevice * dev)472 static int npcm_otp_bind(struct udevice *dev)
473 {
474 struct npcm_otp_regs *regs;
475
476 otp_priv = calloc(1, sizeof(struct npcm_otp_priv));
477 if (!otp_priv)
478 return -ENOMEM;
479
480 regs = dev_remap_addr_index(dev, 0);
481 if (!regs) {
482 printf("Cannot find reg address (arr #0), binding failed\n");
483 return -EINVAL;
484 }
485 otp_priv->regs[0] = regs;
486
487 if (IS_ENABLED(CONFIG_ARCH_NPCM7xx)) {
488 regs = dev_remap_addr_index(dev, 1);
489 if (!regs) {
490 printf("Cannot find reg address (arr #1), binding failed\n");
491 return -EINVAL;
492 }
493 otp_priv->regs[1] = regs;
494 }
495 printf("OTP: NPCM OTP module bind OK\n");
496
497 return 0;
498 }
499
500 static const struct udevice_id npcm_otp_ids[] = {
501 { .compatible = "nuvoton,npcm845-otp" },
502 { .compatible = "nuvoton,npcm750-otp" },
503 { }
504 };
505
506 U_BOOT_DRIVER(npcm_otp) = {
507 .name = "npcm_otp",
508 .id = UCLASS_MISC,
509 .of_match = npcm_otp_ids,
510 .priv_auto = sizeof(struct npcm_otp_priv),
511 .bind = npcm_otp_bind,
512 };
513