1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2021 Nuvoton Technology Corp.
4  */
5 
6 #include <clk.h>
7 #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 
14 struct npcm_otp_priv {
15 	struct npcm_otp_regs *regs[2];
16 };
17 
18 static 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 /*----------------------------------------------------------------------------*/
npcm_otp_check_inputs(u32 arr,u32 word)30 static 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");
35 		if (IS_ENABLED(CONFIG_ARCH_NPCM7xx))
36 			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 /*----------------------------------------------------------------------------*/
npcm_otp_wait_for_otp_ready(u32 arr,u32 timeout)57 static 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 /*----------------------------------------------------------------------------*/
npcm_otp_read_byte(u32 arr,u32 addr,u8 * data)92 static 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 /*----------------------------------------------------------------------------*/
npcm_otp_bit_is_programmed(u32 arr,u32 byte_offset,u8 bit_offset)127 static 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 /*----------------------------------------------------------------------------*/
npcm_otp_program_bit(u32 arr,u32 byte_offset,u8 bit_offset)152 static 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 /*----------------------------------------------------------------------------*/
npcm_otp_program_byte(u32 arr,u32 byte_offset,u8 value)222 static 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 /*----------------------------------------------------------------------------*/
npcm_otp_is_fuse_array_disabled(u32 arr)266 bool 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 
npcm_otp_select_key(u8 key_index)273 int 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 /*----------------------------------------------------------------------------*/
npcm_otp_nibble_parity_ecc_encode(u8 * datain,u8 * dataout,u32 size)318 void 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 /*----------------------------------------------------------------------------*/
npcm_otp_majority_rule_ecc_encode(u8 * datain,u8 * dataout,u32 size)363 void 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 /*----------------------------------------------------------------------------*/
fuse_program_data(u32 bank,u32 word,u8 * data,u32 size)399 int 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 
fuse_prog_image(u32 bank,uintptr_t address)430 int 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 
fuse_read(u32 bank,u32 word,u32 * val)435 int 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 
fuse_sense(u32 bank,u32 word,u32 * val)448 int fuse_sense(u32 bank, u32 word, u32 *val)
449 {
450 	/* We do not support overriding */
451 	return -EINVAL;
452 }
453 
fuse_prog(u32 bank,u32 word,u32 val)454 int 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 
fuse_override(u32 bank,u32 word,u32 val)465 int fuse_override(u32 bank, u32 word, u32 val)
466 {
467 	/* We do not support overriding */
468 	return -EINVAL;
469 }
470 
npcm_otp_bind(struct udevice * dev)471 static 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 
499 static const struct udevice_id npcm_otp_ids[] = {
500 	{ .compatible = "nuvoton,npcm845-otp" },
501 	{ .compatible = "nuvoton,npcm750-otp" },
502 	{ }
503 };
504 
505 U_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 };
512