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