1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2025 Texas Instruments Incorporated, <www.ti.com>
4 */
5
6 #include <errno.h>
7 #include <stdio.h>
8 #include <fuse.h>
9 #include <linux/arm-smccc.h>
10 #include <string.h>
11
12 #define K3_SIP_OTP_WRITEBUFF 0xC2000000
13 #define K3_SIP_OTP_WRITE 0xC2000001
14 #define K3_SIP_OTP_READ 0xC2000002
15
fuse_read(u32 bank,u32 word,u32 * val)16 int fuse_read(u32 bank, u32 word, u32 *val)
17 {
18 struct arm_smccc_res res;
19
20 if (bank != 0U) {
21 printf("Invalid bank argument, ONLY bank 0 is supported\n");
22 return -EINVAL;
23 }
24
25 /* Make SiP SMC call and send the word in the parameter register */
26 arm_smccc_smc(K3_SIP_OTP_READ, word,
27 0, 0, 0, 0, 0, 0, &res);
28
29 *val = res.a1;
30 if (res.a0 != 0)
31 printf("SMC call failed: Error code %lu\n", res.a0);
32
33 return res.a0;
34 }
35
fuse_sense(u32 bank,u32 word,u32 * val)36 int fuse_sense(u32 bank, u32 word, u32 *val)
37 {
38 return -EPERM;
39 }
40
fuse_prog(u32 bank,u32 word,u32 val)41 int fuse_prog(u32 bank, u32 word, u32 val)
42 {
43 struct arm_smccc_res res;
44 u32 mask = val;
45
46 if (bank != 0U) {
47 printf("Invalid bank argument, ONLY bank 0 is supported\n");
48 return -EINVAL;
49 }
50
51 /* Make SiP SMC call and send the word, val and mask in the parameter register */
52 arm_smccc_smc(K3_SIP_OTP_WRITE, word,
53 val, mask, 0, 0, 0, 0, &res);
54
55 if (res.a0 != 0)
56 printf("SMC call failed: Error code %lu\n", res.a0);
57
58 return res.a0;
59 }
60
fuse_override(u32 bank,u32 word,u32 val)61 int fuse_override(u32 bank, u32 word, u32 val)
62 {
63 return -EPERM;
64 }
65
fuse_writebuff(ulong addr)66 int fuse_writebuff(ulong addr)
67 {
68 struct arm_smccc_res res;
69
70 /* Make SiP SMC call and send the addr in the parameter register */
71 arm_smccc_smc(K3_SIP_OTP_WRITEBUFF, (unsigned long)addr,
72 0, 0, 0, 0, 0, 0, &res);
73
74 if (res.a0 != 0)
75 printf("SMC call failed: Error code %lu\n", res.a0);
76
77 return res.a0;
78 }
79