1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2021 Nuvoton Technology Corp.
11 #include <linux/delay.h>
12 #include <asm/arch/otp.h>
14 struct npcm_otp_priv {
15 struct npcm_otp_regs *regs[2];
18 static struct npcm_otp_priv *otp_priv;
20 /*----------------------------------------------------------------------------*/
21 /* Function: npcm_otp_check_inputs */
23 /* Parameters: arr - fuse array number to check */
24 /* word - fuse word (offset) to check */
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 /*----------------------------------------------------------------------------*/
30 static int npcm_otp_check_inputs(u32 arr, u32 word)
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");
35 if (IS_ENABLED(CONFIG_ARCH_NPCM7xx))
36 printf("\nError: npcm7XX otp includs only two banks: 0 and 1\n");
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);
49 /*----------------------------------------------------------------------------*/
50 /* Function: npcm_otp_wait_for_otp_ready */
52 /* Parameters: array - fuse array to wait for */
55 /* Description: Initialize the Fuse HW module. */
56 /*----------------------------------------------------------------------------*/
57 static int npcm_otp_wait_for_otp_ready(u32 arr, u32 timeout)
59 struct npcm_otp_regs *regs = otp_priv->regs[arr];
62 /*------------------------------------------------------------------------*/
63 /* check parameters validity */
64 /*------------------------------------------------------------------------*/
65 if (arr > NPCM_FUSE_SA)
69 if (readl(®s->fst) & FST_RDY) {
70 /* fuse is ready, clear the status. */
71 writel(readl(®s->fst) | FST_RDST, ®s->fst);
76 /* try to clear the status in case it was set */
77 writel(readl(®s->fst) | FST_RDST, ®s->fst);
82 /*----------------------------------------------------------------------------*/
83 /* Function: npcm_otp_read_byte */
85 /* Parameters: arr - Storage Array type [input]. */
86 /* addr - Byte-address to read from [input]. */
87 /* data - Pointer to result [output]. */
90 /* Description: Read 8-bit data from an OTP storage array. */
91 /*----------------------------------------------------------------------------*/
92 static void npcm_otp_read_byte(u32 arr, u32 addr, u8 *data)
94 struct npcm_otp_regs *regs = otp_priv->regs[arr];
96 /* Wait for the Fuse Box Idle */
97 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
99 /* Configure the byte address in the fuse array for read operation */
100 writel(FADDR_VAL(addr, 0), ®s->faddr);
102 /* Initiate a read cycle */
103 writel(READ_INIT, ®s->fctl);
105 /* Wait for read operation completion */
106 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
108 /* Read the result */
109 *data = readl(®s->fdata) & FDATA_MASK;
111 /* Clean FDATA contents to prevent unauthorized software from reading
112 * sensitive information
114 writel(FDATA_CLEAN_VALUE, ®s->fdata);
117 /*----------------------------------------------------------------------------*/
118 /* Function: npcm_otp_bit_is_programmed */
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. */
125 /* Description: Check if a bit is programmed in an OTP storage array. */
126 /*----------------------------------------------------------------------------*/
127 static bool npcm_otp_bit_is_programmed(u32 arr,
128 u32 byte_offset, u8 bit_offset)
132 /* Read the entire byte you wish to program */
133 npcm_otp_read_byte(arr, byte_offset, (u8 *)&data);
135 /* Check whether the bit is already programmed */
136 if (data & (1 << bit_offset))
142 /*----------------------------------------------------------------------------*/
143 /* Function: npcm_otp_program_bit */
145 /* Parameters: arr - Storage Array type [input]. */
146 /* byte)offset - Byte offset in array [input]. */
147 /* bit_offset - Bit offset in byte [input]. */
150 /* Description: Program (set to 1) a bit in an OTP storage array. */
151 /*----------------------------------------------------------------------------*/
152 static int npcm_otp_program_bit(u32 arr, u32 byte_offset,
155 struct npcm_otp_regs *regs = otp_priv->regs[arr];
159 /* Wait for the Fuse Box Idle */
160 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
162 /* Make sure the bit is not already programmed */
163 if (npcm_otp_bit_is_programmed(arr, byte_offset, bit_offset))
166 /* Configure the bit address in the fuse array for program operation */
167 writel(FADDR_VAL(byte_offset, bit_offset), ®s->faddr);
168 writel(readl(®s->faddr) | FADDR_IN_PROG, ®s->faddr);
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, ®s->fctl);
174 writel(PROGRAM_INIT, ®s->fctl);
176 /* Wait for program operation completion */
177 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
179 // after MIN_PROGRAM_PULSES start verifying the result
180 if (count >= MIN_PROGRAM_PULSES) {
181 /* Initiate a read cycle */
182 writel(READ_INIT, ®s->fctl);
184 /* Wait for read operation completion */
185 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
187 /* Read the result */
188 read_data = readl(®s->fdata) & FDATA_MASK;
190 /* If the bit is set the sequence ended correctly */
191 if (read_data & (1 << bit_offset))
196 // check if programmking failed
197 if (count > MAX_PROGRAM_PULSES) {
198 printf("program fail\n");
203 * Clean FDATA contents to prevent unauthorized software from reading
204 * sensitive information
206 writel(FDATA_CLEAN_VALUE, ®s->fdata);
211 /*----------------------------------------------------------------------------*/
212 /* Function: npcm_otp_program_byte */
214 /* Parameters: arr - Storage Array type [input]. */
215 /* byte_offset - Byte offset in array [input]. */
216 /* value - Byte to program [input]. */
219 /* Description: Program (set to 1) a given byte's relevant bits in an */
220 /* OTP storage array. */
221 /*----------------------------------------------------------------------------*/
222 static int npcm_otp_program_byte(u32 arr, u32 byte_offset,
230 rc = npcm_otp_check_inputs(arr, byte_offset);
234 /* Wait for the Fuse Box Idle */
235 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
237 /* Read the entire byte you wish to program */
238 npcm_otp_read_byte(arr, byte_offset, &data);
240 /* In case all relevant bits are already programmed - nothing to do */
241 if ((~data & value) == 0)
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);
250 if (last_status != 0)
251 status = last_status;
257 /*----------------------------------------------------------------------------*/
258 /* Function: npcm_otp_is_fuse_array_disabled */
260 /* Parameters: arr - Storage Array type [input]. */
263 /* Description: Return true if access to the first 2048 bits of the */
264 /* specified fuse array is disabled, false if not */
265 /*----------------------------------------------------------------------------*/
266 bool npcm_otp_is_fuse_array_disabled(u32 arr)
268 struct npcm_otp_regs *regs = otp_priv->regs[arr];
270 return (readl(®s->fcfg) & FCFG_FDIS) != 0;
273 int npcm_otp_select_key(u8 key_index)
275 struct npcm_otp_regs *regs = otp_priv->regs[NPCM_KEY_SA];
277 u32 time = 0xDAEDBEEF;
282 /* Do not destroy ECCDIS bit */
283 idx = readl(®s->fustrap_fkeyind);
285 /* Configure the key size */
286 idx &= ~FKEYIND_KSIZE_MASK;
287 idx |= FKEYIND_KSIZE_256;
289 /* Configure the key index (0 to 3) */
290 idx &= ~FKEYIND_KIND_MASK;
291 idx |= FKEYIND_KIND_KEY(key_index);
293 writel(idx, ®s->fustrap_fkeyind);
295 /* Wait for selection completetion */
297 if (readl(®s->fustrap_fkeyind) & FKEYIND_KVAL)
305 /*----------------------------------------------------------------------------*/
306 /* Function: npcm_otp_nibble_parity_ecc_encode */
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) */
314 /* Description: Decodes the data according to nibble parity ECC scheme. */
315 /* Size specifies the encoded data size. */
316 /* Decodes whole bytes only */
317 /*----------------------------------------------------------------------------*/
318 void npcm_otp_nibble_parity_ecc_encode(u8 *datain, u8 *dataout, u32 size)
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;
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;
336 E0 = (datain[i] >> 4) & 0x01;
337 E1 = (datain[i] >> 5) & 0x01;
338 E2 = (datain[i] >> 6) & 0x01;
339 E3 = (datain[i] >> 7) & 0x01;
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;
350 /*----------------------------------------------------------------------------*/
351 /* Function: npcm_otp_majority_rule_ecc_encode */
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) */
359 /* Description: Decodes the data according to Major Rule ECC scheme. */
360 /* Size specifies the encoded data size. */
361 /* Decodes whole bytes only */
362 /*----------------------------------------------------------------------------*/
363 void npcm_otp_majority_rule_ecc_encode(u8 *datain, u8 *dataout, u32 size)
368 u32 decoded_size = size / 3;
370 for (byte = 0; byte < decoded_size; byte++) {
371 for (bit = 0; bit < 8; bit++) {
372 bit_val = (datain[byte] >> bit) & 0x01;
375 dataout[byte] |= (1 << bit);
376 dataout[decoded_size + byte] |= (1 << bit);
377 dataout[decoded_size * 2 + byte] |= (1 << bit);
379 dataout[byte] &= ~(1 << bit);
380 dataout[decoded_size + byte] &= ~(1 << bit);
381 dataout[decoded_size * 2 + byte] &= ~(1 << bit);
387 /*----------------------------------------------------------------------------*/
388 /* Function: fuse_program_data */
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. */
396 /* Description: Programs the given byte array (size bytes) to the given */
397 /* OTP storage array, starting from offset word. */
398 /*----------------------------------------------------------------------------*/
399 int fuse_program_data(u32 bank, u32 word, u8 *data, u32 size)
405 rc = npcm_otp_check_inputs(bank, word + size - 1);
409 for (byte = 0; byte < size; byte++) {
413 if (val == 0) // optimization
416 rc = npcm_otp_program_byte(arr, word + byte, data[byte]);
420 // verify programming of every '1' bit
422 npcm_otp_read_byte((u32)bank, byte, &val);
423 if ((data[byte] & ~val) != 0)
430 int fuse_prog_image(u32 bank, uintptr_t address)
432 return fuse_program_data(bank, 0, (u8 *)address, NPCM_OTP_ARR_BYTE_SIZE);
435 int fuse_read(u32 bank, u32 word, u32 *val)
437 int rc = npcm_otp_check_inputs(bank, word);
443 npcm_otp_read_byte((u32)bank, word, (u8 *)val);
448 int fuse_sense(u32 bank, u32 word, u32 *val)
450 /* We do not support overriding */
454 int fuse_prog(u32 bank, u32 word, u32 val)
458 rc = npcm_otp_check_inputs(bank, word);
462 return npcm_otp_program_byte(bank, word, (u8)val);
465 int fuse_override(u32 bank, u32 word, u32 val)
467 /* We do not support overriding */
471 static int npcm_otp_bind(struct udevice *dev)
473 struct npcm_otp_regs *regs;
475 otp_priv = calloc(1, sizeof(struct npcm_otp_priv));
479 regs = dev_remap_addr_index(dev, 0);
481 printf("Cannot find reg address (arr #0), binding failed\n");
484 otp_priv->regs[0] = regs;
486 if (IS_ENABLED(CONFIG_ARCH_NPCM7xx)) {
487 regs = dev_remap_addr_index(dev, 1);
489 printf("Cannot find reg address (arr #1), binding failed\n");
492 otp_priv->regs[1] = regs;
494 printf("OTP: NPCM OTP module bind OK\n");
499 static const struct udevice_id npcm_otp_ids[] = {
500 { .compatible = "nuvoton,npcm845-otp" },
501 { .compatible = "nuvoton,npcm750-otp" },
505 U_BOOT_DRIVER(npcm_otp) = {
508 .of_match = npcm_otp_ids,
509 .priv_auto = sizeof(struct npcm_otp_priv),
510 .bind = npcm_otp_bind,