blob: 08029724c04097e3659077f9645c36641c4ce60b [file] [log] [blame]
Jim Liu0ae1c772022-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>
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
15struct npcm_otp_priv {
16 struct npcm_otp_regs *regs[2];
17};
18
19static 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/*----------------------------------------------------------------------------*/
31static 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");
Jim Liu923edd62023-06-13 15:45:56 +080036 if (IS_ENABLED(CONFIG_ARCH_NPCM7xx))
Jim Liu0ae1c772022-06-07 16:33:54 +080037 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/*----------------------------------------------------------------------------*/
58static 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/*----------------------------------------------------------------------------*/
93static 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/*----------------------------------------------------------------------------*/
128static 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/*----------------------------------------------------------------------------*/
153static 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/*----------------------------------------------------------------------------*/
223static 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/*----------------------------------------------------------------------------*/
267bool 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
274int 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/*----------------------------------------------------------------------------*/
319void 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/*----------------------------------------------------------------------------*/
364void 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/*----------------------------------------------------------------------------*/
400int 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
431int 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
436int 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
449int fuse_sense(u32 bank, u32 word, u32 *val)
450{
451 /* We do not support overriding */
452 return -EINVAL;
453}
454
455int 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
466int fuse_override(u32 bank, u32 word, u32 val)
467{
468 /* We do not support overriding */
469 return -EINVAL;
470}
471
472static 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
500static const struct udevice_id npcm_otp_ids[] = {
501 { .compatible = "nuvoton,npcm845-otp" },
502 { .compatible = "nuvoton,npcm750-otp" },
503 { }
504};
505
506U_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};