1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2021 Nuvoton Technology Corp.
12 #include <linux/delay.h>
13 #include <asm/arch/otp.h>
15 struct npcm_otp_priv {
16 struct npcm_otp_regs *regs[2];
19 static struct npcm_otp_priv *otp_priv;
21 /*----------------------------------------------------------------------------*/
22 /* Function: npcm_otp_check_inputs */
24 /* Parameters: arr - fuse array number to check */
25 /* word - fuse word (offset) to check */
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 /*----------------------------------------------------------------------------*/
31 static int npcm_otp_check_inputs(u32 arr, u32 word)
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");
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);
50 /*----------------------------------------------------------------------------*/
51 /* Function: npcm_otp_wait_for_otp_ready */
53 /* Parameters: array - fuse array to wait for */
56 /* Description: Initialize the Fuse HW module. */
57 /*----------------------------------------------------------------------------*/
58 static int npcm_otp_wait_for_otp_ready(u32 arr, u32 timeout)
60 struct npcm_otp_regs *regs = otp_priv->regs[arr];
63 /*------------------------------------------------------------------------*/
64 /* check parameters validity */
65 /*------------------------------------------------------------------------*/
66 if (arr > NPCM_FUSE_SA)
70 if (readl(®s->fst) & FST_RDY) {
71 /* fuse is ready, clear the status. */
72 writel(readl(®s->fst) | FST_RDST, ®s->fst);
77 /* try to clear the status in case it was set */
78 writel(readl(®s->fst) | FST_RDST, ®s->fst);
83 /*----------------------------------------------------------------------------*/
84 /* Function: npcm_otp_read_byte */
86 /* Parameters: arr - Storage Array type [input]. */
87 /* addr - Byte-address to read from [input]. */
88 /* data - Pointer to result [output]. */
91 /* Description: Read 8-bit data from an OTP storage array. */
92 /*----------------------------------------------------------------------------*/
93 static void npcm_otp_read_byte(u32 arr, u32 addr, u8 *data)
95 struct npcm_otp_regs *regs = otp_priv->regs[arr];
97 /* Wait for the Fuse Box Idle */
98 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
100 /* Configure the byte address in the fuse array for read operation */
101 writel(FADDR_VAL(addr, 0), ®s->faddr);
103 /* Initiate a read cycle */
104 writel(READ_INIT, ®s->fctl);
106 /* Wait for read operation completion */
107 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
109 /* Read the result */
110 *data = readl(®s->fdata) & FDATA_MASK;
112 /* Clean FDATA contents to prevent unauthorized software from reading
113 * sensitive information
115 writel(FDATA_CLEAN_VALUE, ®s->fdata);
118 /*----------------------------------------------------------------------------*/
119 /* Function: npcm_otp_bit_is_programmed */
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. */
126 /* Description: Check if a bit is programmed in an OTP storage array. */
127 /*----------------------------------------------------------------------------*/
128 static bool npcm_otp_bit_is_programmed(u32 arr,
129 u32 byte_offset, u8 bit_offset)
133 /* Read the entire byte you wish to program */
134 npcm_otp_read_byte(arr, byte_offset, (u8 *)&data);
136 /* Check whether the bit is already programmed */
137 if (data & (1 << bit_offset))
143 /*----------------------------------------------------------------------------*/
144 /* Function: npcm_otp_program_bit */
146 /* Parameters: arr - Storage Array type [input]. */
147 /* byte)offset - Byte offset in array [input]. */
148 /* bit_offset - Bit offset in byte [input]. */
151 /* Description: Program (set to 1) a bit in an OTP storage array. */
152 /*----------------------------------------------------------------------------*/
153 static int npcm_otp_program_bit(u32 arr, u32 byte_offset,
156 struct npcm_otp_regs *regs = otp_priv->regs[arr];
160 /* Wait for the Fuse Box Idle */
161 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
163 /* Make sure the bit is not already programmed */
164 if (npcm_otp_bit_is_programmed(arr, byte_offset, bit_offset))
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);
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);
177 /* Wait for program operation completion */
178 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
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);
185 /* Wait for read operation completion */
186 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
188 /* Read the result */
189 read_data = readl(®s->fdata) & FDATA_MASK;
191 /* If the bit is set the sequence ended correctly */
192 if (read_data & (1 << bit_offset))
197 // check if programmking failed
198 if (count > MAX_PROGRAM_PULSES) {
199 printf("program fail\n");
204 * Clean FDATA contents to prevent unauthorized software from reading
205 * sensitive information
207 writel(FDATA_CLEAN_VALUE, ®s->fdata);
212 /*----------------------------------------------------------------------------*/
213 /* Function: npcm_otp_program_byte */
215 /* Parameters: arr - Storage Array type [input]. */
216 /* byte_offset - Byte offset in array [input]. */
217 /* value - Byte to program [input]. */
220 /* Description: Program (set to 1) a given byte's relevant bits in an */
221 /* OTP storage array. */
222 /*----------------------------------------------------------------------------*/
223 static int npcm_otp_program_byte(u32 arr, u32 byte_offset,
231 rc = npcm_otp_check_inputs(arr, byte_offset);
235 /* Wait for the Fuse Box Idle */
236 npcm_otp_wait_for_otp_ready(arr, 0xDEADBEEF);
238 /* Read the entire byte you wish to program */
239 npcm_otp_read_byte(arr, byte_offset, &data);
241 /* In case all relevant bits are already programmed - nothing to do */
242 if ((~data & value) == 0)
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);
251 if (last_status != 0)
252 status = last_status;
258 /*----------------------------------------------------------------------------*/
259 /* Function: npcm_otp_is_fuse_array_disabled */
261 /* Parameters: arr - Storage Array type [input]. */
264 /* Description: Return true if access to the first 2048 bits of the */
265 /* specified fuse array is disabled, false if not */
266 /*----------------------------------------------------------------------------*/
267 bool npcm_otp_is_fuse_array_disabled(u32 arr)
269 struct npcm_otp_regs *regs = otp_priv->regs[arr];
271 return (readl(®s->fcfg) & FCFG_FDIS) != 0;
274 int npcm_otp_select_key(u8 key_index)
276 struct npcm_otp_regs *regs = otp_priv->regs[NPCM_KEY_SA];
278 u32 time = 0xDAEDBEEF;
283 /* Do not destroy ECCDIS bit */
284 idx = readl(®s->fustrap_fkeyind);
286 /* Configure the key size */
287 idx &= ~FKEYIND_KSIZE_MASK;
288 idx |= FKEYIND_KSIZE_256;
290 /* Configure the key index (0 to 3) */
291 idx &= ~FKEYIND_KIND_MASK;
292 idx |= FKEYIND_KIND_KEY(key_index);
294 writel(idx, ®s->fustrap_fkeyind);
296 /* Wait for selection completetion */
298 if (readl(®s->fustrap_fkeyind) & FKEYIND_KVAL)
306 /*----------------------------------------------------------------------------*/
307 /* Function: npcm_otp_nibble_parity_ecc_encode */
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) */
315 /* Description: Decodes the data according to nibble parity ECC scheme. */
316 /* Size specifies the encoded data size. */
317 /* Decodes whole bytes only */
318 /*----------------------------------------------------------------------------*/
319 void npcm_otp_nibble_parity_ecc_encode(u8 *datain, u8 *dataout, u32 size)
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;
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;
337 E0 = (datain[i] >> 4) & 0x01;
338 E1 = (datain[i] >> 5) & 0x01;
339 E2 = (datain[i] >> 6) & 0x01;
340 E3 = (datain[i] >> 7) & 0x01;
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;
351 /*----------------------------------------------------------------------------*/
352 /* Function: npcm_otp_majority_rule_ecc_encode */
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) */
360 /* Description: Decodes the data according to Major Rule ECC scheme. */
361 /* Size specifies the encoded data size. */
362 /* Decodes whole bytes only */
363 /*----------------------------------------------------------------------------*/
364 void npcm_otp_majority_rule_ecc_encode(u8 *datain, u8 *dataout, u32 size)
369 u32 decoded_size = size / 3;
371 for (byte = 0; byte < decoded_size; byte++) {
372 for (bit = 0; bit < 8; bit++) {
373 bit_val = (datain[byte] >> bit) & 0x01;
376 dataout[byte] |= (1 << bit);
377 dataout[decoded_size + byte] |= (1 << bit);
378 dataout[decoded_size * 2 + byte] |= (1 << bit);
380 dataout[byte] &= ~(1 << bit);
381 dataout[decoded_size + byte] &= ~(1 << bit);
382 dataout[decoded_size * 2 + byte] &= ~(1 << bit);
388 /*----------------------------------------------------------------------------*/
389 /* Function: fuse_program_data */
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. */
397 /* Description: Programs the given byte array (size bytes) to the given */
398 /* OTP storage array, starting from offset word. */
399 /*----------------------------------------------------------------------------*/
400 int fuse_program_data(u32 bank, u32 word, u8 *data, u32 size)
406 rc = npcm_otp_check_inputs(bank, word + size - 1);
410 for (byte = 0; byte < size; byte++) {
414 if (val == 0) // optimization
417 rc = npcm_otp_program_byte(arr, word + byte, data[byte]);
421 // verify programming of every '1' bit
423 npcm_otp_read_byte((u32)bank, byte, &val);
424 if ((data[byte] & ~val) != 0)
431 int fuse_prog_image(u32 bank, uintptr_t address)
433 return fuse_program_data(bank, 0, (u8 *)address, NPCM_OTP_ARR_BYTE_SIZE);
436 int fuse_read(u32 bank, u32 word, u32 *val)
438 int rc = npcm_otp_check_inputs(bank, word);
444 npcm_otp_read_byte((u32)bank, word, (u8 *)val);
449 int fuse_sense(u32 bank, u32 word, u32 *val)
451 /* We do not support overriding */
455 int fuse_prog(u32 bank, u32 word, u32 val)
459 rc = npcm_otp_check_inputs(bank, word);
463 return npcm_otp_program_byte(bank, word, (u8)val);
466 int fuse_override(u32 bank, u32 word, u32 val)
468 /* We do not support overriding */
472 static int npcm_otp_bind(struct udevice *dev)
474 struct npcm_otp_regs *regs;
476 otp_priv = calloc(1, sizeof(struct npcm_otp_priv));
480 regs = dev_remap_addr_index(dev, 0);
482 printf("Cannot find reg address (arr #0), binding failed\n");
485 otp_priv->regs[0] = regs;
487 if (IS_ENABLED(CONFIG_ARCH_NPCM7xx)) {
488 regs = dev_remap_addr_index(dev, 1);
490 printf("Cannot find reg address (arr #1), binding failed\n");
493 otp_priv->regs[1] = regs;
495 printf("OTP: NPCM OTP module bind OK\n");
500 static const struct udevice_id npcm_otp_ids[] = {
501 { .compatible = "nuvoton,npcm845-otp" },
502 { .compatible = "nuvoton,npcm750-otp" },
506 U_BOOT_DRIVER(npcm_otp) = {
509 .of_match = npcm_otp_ids,
510 .priv_auto = sizeof(struct npcm_otp_priv),
511 .bind = npcm_otp_bind,