1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #ifndef __DA1469X_OTP_H_
21 #define __DA1469X_OTP_H_
22
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <assert.h>
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 #define OTP_ERR_INVALID_SIZE_ALIGNMENT -1
32 #define OTP_ERR_INVALID_ADDRESS -2
33 #define OTP_ERR_PROGRAM_VERIFY_FAILED -3
34
35 #define OTP_SEGMENT_CONFIG 0xc00
36 #define OTP_SEGMENT_QSPI_FW_KEYS 0xb00
37 #define OTP_SEGMENT_USER_DATA_KEYS 0xa00
38 #define OTP_SEGMENT_SIGNATURE_KEYS 0x8c0
39 #define OTP_SEGMENT_USER_DATA_LEN 0x100
40 #define OTP_SEGMENT_QSPI_FW_LEN 0x100
41
42 #define IS_ADDRESS_USER_DATA_KEYS_SEGMENT(_a) \
43 ((((uint32_t)(_a) >= (uint32_t)MCU_OTP_M_BASE + OTP_SEGMENT_USER_DATA_KEYS) && \
44 ((uint32_t)(_a) < (uint32_t)MCU_OTP_M_BASE + OTP_SEGMENT_USER_DATA_KEYS + OTP_SEGMENT_USER_DATA_LEN)) || \
45 (((uint32_t)(_a) >= (uint32_t)MCU_OTP_M_P_BASE + OTP_SEGMENT_USER_DATA_KEYS) && \
46 ((uint32_t)(_a) < (uint32_t)MCU_OTP_M_P_BASE + OTP_SEGMENT_USER_DATA_KEYS + OTP_SEGMENT_USER_DATA_LEN)))
47
48 #define IS_ADDRESS_QSPI_FW_KEYS_SEGMENT(_a) \
49 ((((uint32_t)(_a) >= (uint32_t)MCU_OTP_M_BASE + OTP_SEGMENT_QSPI_FW_KEYS) && \
50 ((uint32_t)(_a) < (uint32_t)MCU_OTP_M_BASE + OTP_SEGMENT_QSPI_FW_KEYS + OTP_SEGMENT_QSPI_FW_LEN)) || \
51 (((uint32_t)(_a) >= (uint32_t)MCU_OTP_M_P_BASE + OTP_SEGMENT_QSPI_FW_KEYS) && \
52 ((uint32_t)(_a) < (uint32_t)MCU_OTP_M_P_BASE + OTP_SEGMENT_QSPI_FW_KEYS + OTP_SEGMENT_QSPI_FW_LEN)))
53
54 enum otpc_mode_val {
55 OTPC_MODE_PDOWN = 0,
56 OTPC_MODE_DSTBY,
57 OTPC_MODE_STBY,
58 OTPC_MODE_READ,
59 OTPC_MODE_PROG,
60 OTPC_MODE_PVFY,
61 OTPC_MODE_RINI,
62 };
63
64 static inline void
da1469x_otp_set_mode(enum otpc_mode_val mode)65 da1469x_otp_set_mode(enum otpc_mode_val mode)
66 {
67 OTPC->OTPC_MODE_REG = (OTPC->OTPC_MODE_REG &
68 ~OTPC_OTPC_MODE_REG_OTPC_MODE_MODE_Msk) |
69 (mode << OTPC_OTPC_MODE_REG_OTPC_MODE_MODE_Pos);
70 while (!(OTPC->OTPC_STAT_REG & OTPC_OTPC_STAT_REG_OTPC_STAT_MRDY_Msk));
71 }
72
73 static inline uint32_t
da1469x_otp_address_to_cell_offset(uint32_t addr)74 da1469x_otp_address_to_cell_offset(uint32_t addr)
75 {
76 assert(IS_OTP_ADDRESS(addr) || IS_OTP_P_ADDRESS(addr));
77 /* Address should be cell size alinged */
78 assert(!(addr % 4));
79
80 if (addr < MCU_OTP_M_P_BASE) {
81 return (addr - MCU_OTP_M_BASE) / 4;
82 } else {
83 return (addr - MCU_OTP_M_P_BASE) / 4;
84 }
85 }
86
87 int da1469x_otp_write(uint32_t offset, const void *src,
88 uint32_t num_bytes);
89
90 int da1469x_otp_read(uint32_t offset, void *dst, uint32_t num_bytes);
91
92 void da1469x_otp_init(void);
93
94 void da1469x_otp_set_speed(uint32_t clk_speed);
95
96
97 #ifdef __cplusplus
98 }
99 #endif
100
101 #endif /* __MCU_DA1469X_OTP_H_ */
102