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(&regs->fst) & FST_RDY) {
71 			/* fuse is ready, clear the status. */
72 			writel(readl(&regs->fst) | FST_RDST, &regs->fst);
73 			return 0;
74 		}
75 	}
76 
77 	/* try to clear the status in case it was set */
78 	writel(readl(&regs->fst) | FST_RDST, &regs->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), &regs->faddr);
102 
103 	/* Initiate a read cycle */
104 	writel(READ_INIT, &regs->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(&regs->fdata) & FDATA_MASK;
111 
112 	/* Clean FDATA contents to prevent unauthorized software from reading
113 	 * sensitive information
114 	 */
115 	writel(FDATA_CLEAN_VALUE, &regs->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), &regs->faddr);
169 	writel(readl(&regs->faddr) | FADDR_IN_PROG, &regs->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, &regs->fctl);
175 		writel(PROGRAM_INIT, &regs->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, &regs->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(&regs->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, &regs->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(&regs->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(&regs->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, &regs->fustrap_fkeyind);
295 
296 	/* Wait for selection completetion */
297 	while (--time > 1) {
298 		if (readl(&regs->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