1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
4 * Copyright (c) 2024, Rockchip, Inc. All rights reserved.
5 * Copyright (C) 2025, Pengutronix, Michael Tretter <m.tretter@pengutronix.de>
6 */
7
8 #include <common.h>
9 #include <drivers/rockchip_otp.h>
10 #include <io.h>
11 #include <kernel/panic.h>
12 #include <kernel/tee_common_otp.h>
13 #include <mm/core_memprot.h>
14 #include <utee_defines.h>
15
16 #define OTP_S_AUTO_CTRL 0x0004
17 #define OTP_S_AUTO_EN 0x0008
18 #define OTP_S_PROG_DATA 0x0010
19 #define OTP_S_DOUT 0x0020
20 #define OTP_S_INT_ST 0x0084
21
22 #define ADDR_SHIFT 16
23 #define BURST_SHIFT 8
24 #define CMD_READ 0
25 #define CMD_WRITE 2
26 #define EN_ENABLE 1
27 #define EN_DISABLE 0
28
29 #define MAX_INDEX 0x300
30 #define BURST_SIZE 8
31 #define OTP_WORD 1
32
33 #define OTP_S_ERROR_BIT BIT32(4)
34 #define OTP_S_WR_DONE_BIT BIT32(3)
35 #define OTP_S_VERIFY_BIT BIT32(2)
36 #define OTP_S_RD_DONE_BIT BIT32(1)
37
38 #define OTP_POLL_PERIOD_US 0
39 #define OTP_POLL_TIMEOUT_US 1000
40
41 register_phys_mem_pgdir(MEM_AREA_IO_SEC, OTP_S_BASE, OTP_S_SIZE);
42
rockchip_otp_read_secure(uint32_t * value,uint32_t index,uint32_t count)43 TEE_Result rockchip_otp_read_secure(uint32_t *value, uint32_t index,
44 uint32_t count)
45 {
46 vaddr_t base = (vaddr_t)phys_to_virt(OTP_S_BASE, MEM_AREA_IO_SEC,
47 OTP_S_SIZE);
48 uint32_t int_status = 0;
49 uint32_t i = 0;
50 uint32_t val = 0;
51 uint32_t auto_ctrl_val = 0;
52 TEE_Result res = TEE_SUCCESS;
53
54 if (!base)
55 panic("OTP_S base not mapped");
56
57 /* Check for invalid parameters or exceeding hardware burst limit */
58 if (!value || !count || count > BURST_SIZE ||
59 (index + count > MAX_INDEX))
60 return TEE_ERROR_BAD_PARAMETERS;
61
62 /* Setup read: index, count, command = READ */
63 auto_ctrl_val = SHIFT_U32(index, ADDR_SHIFT) |
64 SHIFT_U32(count, BURST_SHIFT) |
65 CMD_READ;
66
67 /* Clear any pending interrupts by reading & writing back INT_ST */
68 io_write32(base + OTP_S_INT_ST, io_read32(base + OTP_S_INT_ST));
69
70 /* Set read command */
71 io_write32(base + OTP_S_AUTO_CTRL, auto_ctrl_val);
72
73 /* Enable read */
74 io_write32(base + OTP_S_AUTO_EN, EN_ENABLE);
75
76 /* Wait for RD_DONE or ERROR bits */
77 res = IO_READ32_POLL_TIMEOUT(base + OTP_S_INT_ST,
78 int_status,
79 (int_status & OTP_S_RD_DONE_BIT) ||
80 (int_status & OTP_S_ERROR_BIT),
81 OTP_POLL_PERIOD_US,
82 OTP_POLL_TIMEOUT_US);
83
84 /* Clear the interrupt again */
85 io_write32(base + OTP_S_INT_ST, io_read32(base + OTP_S_INT_ST));
86
87 if (int_status & OTP_S_ERROR_BIT) {
88 EMSG("OTP_S Error");
89 return TEE_ERROR_GENERIC;
90 }
91 if (res) {
92 EMSG("OTP_S Timeout");
93 return TEE_ERROR_BUSY;
94 }
95
96 /* Read out the data */
97 for (i = 0; i < count; i++) {
98 val = io_read32(base + OTP_S_DOUT +
99 (i * sizeof(uint32_t)));
100 value[i] = val;
101 }
102
103 return TEE_SUCCESS;
104 }
105
rockchip_otp_write_secure(const uint32_t * value,uint32_t index,uint32_t count)106 TEE_Result rockchip_otp_write_secure(const uint32_t *value, uint32_t index,
107 uint32_t count)
108 {
109 vaddr_t base = (vaddr_t)phys_to_virt(OTP_S_BASE, MEM_AREA_IO_SEC,
110 OTP_S_SIZE);
111 uint32_t int_status = 0;
112 uint32_t i = 0;
113
114 if (!base)
115 panic("OTP_S base not mapped");
116
117 /* Check for invalid parameters or exceeding hardware limits */
118 if (!value || !count || count > BURST_SIZE ||
119 (index + count > MAX_INDEX))
120 return TEE_ERROR_BAD_PARAMETERS;
121
122 /* Program OTP words */
123 for (i = 0; i < count; i++) {
124 uint32_t old_val = 0;
125 uint32_t new_val = 0;
126 uint32_t curr_idx = index + i;
127 TEE_Result res = TEE_SUCCESS;
128
129 /* Setup write: curr_idx, command = WRITE */
130 uint32_t auto_ctrl_val = SHIFT_U32(curr_idx, ADDR_SHIFT) |
131 CMD_WRITE;
132
133 /* Read existing OTP word to see which bits can be set */
134 res = rockchip_otp_read_secure(&old_val, curr_idx, OTP_WORD);
135 if (res != TEE_SUCCESS)
136 return res;
137
138 /* Check if bits in value conflict with old_val */
139 if (~*value & old_val) {
140 EMSG("OTP_S Program fail");
141 return TEE_ERROR_GENERIC;
142 }
143
144 /* Only program bits that are currently 0 (0->1) */
145 new_val = *value & ~old_val;
146 value++;
147 if (!new_val)
148 continue;
149
150 /* Clear any pending interrupts */
151 io_write32(base + OTP_S_INT_ST, io_read32(base + OTP_S_INT_ST));
152
153 /* Set write command */
154 io_write32(base + OTP_S_AUTO_CTRL, auto_ctrl_val);
155
156 /* Write the new bits into PROG_DATA register */
157 io_write32(base + OTP_S_PROG_DATA, new_val);
158
159 /* Enable the write */
160 io_write32(base + OTP_S_AUTO_EN, EN_ENABLE);
161
162 /* Poll for WR_DONE or verify/error bits */
163 res = IO_READ32_POLL_TIMEOUT(base + OTP_S_INT_ST,
164 int_status,
165 (int_status & OTP_S_WR_DONE_BIT) ||
166 (int_status & OTP_S_VERIFY_BIT) ||
167 (int_status & OTP_S_ERROR_BIT),
168 OTP_POLL_PERIOD_US,
169 OTP_POLL_TIMEOUT_US);
170
171 /* Clear INT status bits */
172 io_write32(base + OTP_S_INT_ST, int_status);
173
174 /* Check for VERIFY_FAIL, ERROR or timeout */
175 if (int_status & OTP_S_VERIFY_BIT) {
176 EMSG("OTP_S Verification fail");
177 return TEE_ERROR_GENERIC;
178 }
179 if (int_status & OTP_S_ERROR_BIT) {
180 EMSG("OTP_S Error");
181 return TEE_ERROR_GENERIC;
182 }
183 if (res) {
184 EMSG("OTP_S Timeout");
185 return TEE_ERROR_BUSY;
186 }
187 }
188
189 return TEE_SUCCESS;
190 }
191