1 /*
2  * Copyright 2018-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  */
8 
9 #include "fsl_iap.h"
10 
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.iap"
14 #endif
15 
16 /*!
17  * @addtogroup rom_api
18  * @{
19  */
20 
21 /*******************************************************************************
22  * Definitions
23  ******************************************************************************/
24 /*! @brief FLEXSPI Flash driver API Interface */
25 typedef struct
26 {
27     uint32_t version;
28     status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
29     status_t (*page_program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dstAddr, const uint32_t *src);
30     status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
31     status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
32     status_t (*erase_sector)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
33     status_t (*erase_block)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
34     status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
35     status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
36     status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
37     status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
38     status_t (*set_clock_source)(uint32_t clockSrc);
39     void (*config_clock)(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode);
40 } flexspi_nor_flash_driver_t;
41 
42 /*! @brief OTP driver API Interface */
43 typedef struct
44 {
45     status_t (*init)(uint32_t src_clk_freq);
46     status_t (*deinit)(void);
47     status_t (*fuse_read)(uint32_t addr, uint32_t *data);
48     status_t (*fuse_program)(uint32_t addr, uint32_t data, bool lock);
49     status_t (*crc_calc)(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum);
50     status_t (*reload)(void);
51     status_t (*crc_check)(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr);
52 } ocotp_driver_t;
53 
54 /*!
55  * @brief Root of the bootloader API tree.
56  *
57  * An instance of this struct resides in read-only memory in the bootloader. It
58  * provides a user application access to APIs exported by the bootloader.
59  *
60  * @note The order of existing fields must not be changed.
61  */
62 typedef struct BootloaderTree
63 {
64     void (*runBootloader)(iap_boot_option_t *arg); /*!< Function to start the bootloader executing. */
65     uint32_t version;                              /*!< Bootloader version number. */
66     const char *copyright;                         /*!< Copyright string. */
67     const uint32_t reserved0;
68     const uint32_t reserved1;
69     const uint32_t reserved2;
70     const uint32_t reserved3;
71     const flexspi_nor_flash_driver_t *flexspiNorDriver; /*!< FlexSPI NOR FLASH Driver API. */
72     const ocotp_driver_t *otpDriver;                    /*!< OTP driver API. */
73     const uint32_t reserved4;
74 } bootloader_tree_t;
75 
76 /*******************************************************************************
77  * Definitions
78  ******************************************************************************/
79 #define ROM_API_TREE                ((uint32_t *)FSL_ROM_API_BASE_ADDR)
80 #define BOOTLOADER_API_TREE_POINTER ((bootloader_tree_t *)ROM_API_TREE)
81 
82 /*! Get pointer to flexspi/otp driver API table in ROM. */
83 #define FLEXSPI_API_TREE BOOTLOADER_API_TREE_POINTER->flexspiNorDriver
84 #define OTP_API_TREE     BOOTLOADER_API_TREE_POINTER->otpDriver
85 
86 /*******************************************************************************
87  * Variables
88  ******************************************************************************/
89 
90 /*******************************************************************************
91  * runBootloader API
92  ******************************************************************************/
IAP_RunBootLoader(iap_boot_option_t * option)93 void IAP_RunBootLoader(iap_boot_option_t *option)
94 {
95     BOOTLOADER_API_TREE_POINTER->runBootloader(option);
96 }
97 
98 /*******************************************************************************
99  * FlexSPI NOR driver
100  ******************************************************************************/
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorInit (uint32_t instance,flexspi_nor_config_t * config))101 AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config))
102 {
103     return FLEXSPI_API_TREE->init(instance, config);
104 }
105 
IAP_FlexspiNorPageProgram(uint32_t instance,flexspi_nor_config_t * config,uint32_t dstAddr,const uint32_t * src)106 status_t IAP_FlexspiNorPageProgram(uint32_t instance,
107                                    flexspi_nor_config_t *config,
108                                    uint32_t dstAddr,
109                                    const uint32_t *src)
110 {
111     return FLEXSPI_API_TREE->page_program(instance, config, dstAddr, src);
112 }
113 
IAP_FlexspiNorEraseAll(uint32_t instance,flexspi_nor_config_t * config)114 status_t IAP_FlexspiNorEraseAll(uint32_t instance, flexspi_nor_config_t *config)
115 {
116     return FLEXSPI_API_TREE->erase_all(instance, config);
117 }
118 
IAP_FlexspiNorErase(uint32_t instance,flexspi_nor_config_t * config,uint32_t start,uint32_t length)119 status_t IAP_FlexspiNorErase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length)
120 {
121     return FLEXSPI_API_TREE->erase(instance, config, start, length);
122 }
123 
IAP_FlexspiNorEraseSector(uint32_t instance,flexspi_nor_config_t * config,uint32_t address)124 status_t IAP_FlexspiNorEraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address)
125 {
126     return FLEXSPI_API_TREE->erase_sector(instance, config, address);
127 }
128 
IAP_FlexspiNorEraseBlock(uint32_t instance,flexspi_nor_config_t * config,uint32_t address)129 status_t IAP_FlexspiNorEraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t address)
130 {
131     return FLEXSPI_API_TREE->erase_block(instance, config, address);
132 }
133 
IAP_FlexspiNorGetConfig(uint32_t instance,flexspi_nor_config_t * config,serial_nor_config_option_t * option)134 status_t IAP_FlexspiNorGetConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option)
135 {
136     return FLEXSPI_API_TREE->get_config(instance, config, option);
137 }
138 
IAP_FlexspiNorRead(uint32_t instance,flexspi_nor_config_t * config,uint32_t * dst,uint32_t start,uint32_t bytes)139 status_t IAP_FlexspiNorRead(
140     uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes)
141 {
142     return FLEXSPI_API_TREE->read(instance, config, dst, start, bytes);
143 }
144 
IAP_FlexspiXfer(uint32_t instance,flexspi_xfer_t * xfer)145 status_t IAP_FlexspiXfer(uint32_t instance, flexspi_xfer_t *xfer)
146 {
147     return FLEXSPI_API_TREE->xfer(instance, xfer);
148 }
149 
IAP_FlexspiUpdateLut(uint32_t instance,uint32_t seqIndex,const uint32_t * lutBase,uint32_t numberOfSeq)150 status_t IAP_FlexspiUpdateLut(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq)
151 {
152     return FLEXSPI_API_TREE->update_lut(instance, seqIndex, lutBase, numberOfSeq);
153 }
154 
IAP_FlexspiSetClockSource(uint32_t clockSrc)155 status_t IAP_FlexspiSetClockSource(uint32_t clockSrc)
156 {
157     return FLEXSPI_API_TREE->set_clock_source(clockSrc);
158 }
159 
IAP_FlexspiConfigClock(uint32_t instance,uint32_t freqOption,uint32_t sampleClkMode)160 void IAP_FlexspiConfigClock(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode)
161 {
162     FLEXSPI_API_TREE->config_clock(instance, freqOption, sampleClkMode);
163 }
164 
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorAutoConfig (uint32_t instance,flexspi_nor_config_t * config,serial_nor_config_option_t * option))165 AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorAutoConfig(uint32_t instance,
166                                                               flexspi_nor_config_t *config,
167                                                               serial_nor_config_option_t *option))
168 {
169     /* Wait until the FLEXSPI is idle */
170     register uint32_t delaycnt = 10000u;
171     status_t status;
172 
173     while ((delaycnt--) != 0U)
174     {
175     }
176 
177     status = FLEXSPI_API_TREE->get_config(instance, config, option);
178     if (status == kStatus_Success)
179     {
180         status = FLEXSPI_API_TREE->init(instance, config);
181     }
182 
183     return status;
184 }
185 
186 /*******************************************************************************
187  * OTP driver
188  ******************************************************************************/
IAP_OtpInit(uint32_t src_clk_freq)189 status_t IAP_OtpInit(uint32_t src_clk_freq)
190 {
191     return OTP_API_TREE->init(src_clk_freq);
192 }
193 
IAP_OtpDeinit(void)194 status_t IAP_OtpDeinit(void)
195 {
196     return OTP_API_TREE->deinit();
197 }
198 
IAP_OtpFuseRead(uint32_t addr,uint32_t * data)199 status_t IAP_OtpFuseRead(uint32_t addr, uint32_t *data)
200 {
201     return OTP_API_TREE->fuse_read(addr, data);
202 }
203 
IAP_OtpFuseProgram(uint32_t addr,uint32_t data,bool lock)204 status_t IAP_OtpFuseProgram(uint32_t addr, uint32_t data, bool lock)
205 {
206     return OTP_API_TREE->fuse_program(addr, data, lock);
207 }
208 
IAP_OtpCrcCalc(uint32_t * src,uint32_t numberOfWords,uint32_t * crcChecksum)209 status_t IAP_OtpCrcCalc(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum)
210 {
211     return OTP_API_TREE->crc_calc(src, numberOfWords, crcChecksum);
212 }
213 
IAP_OtpShadowRegisterReload(void)214 status_t IAP_OtpShadowRegisterReload(void)
215 {
216     return OTP_API_TREE->reload();
217 }
218 
IAP_OtpCrcCheck(uint32_t start_addr,uint32_t end_addr,uint32_t crc_addr)219 status_t IAP_OtpCrcCheck(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr)
220 {
221     return OTP_API_TREE->crc_check(start_addr, end_addr, crc_addr);
222 }
223