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