1 /******************************************************************************
2 *  Filename:       flash.c
3 *  Revised:        2020-05-14 17:23:02 +0200 (Thu, 14 May 2020)
4 *  Revision:       57519
5 *
6 *  Description:    Driver for on chip Flash.
7 *
8 *  Copyright (c) 2015 - 2020, Texas Instruments Incorporated
9 *  All rights reserved.
10 *
11 *  Redistribution and use in source and binary forms, with or without
12 *  modification, are permitted provided that the following conditions are met:
13 *
14 *  1) Redistributions of source code must retain the above copyright notice,
15 *     this list of conditions and the following disclaimer.
16 *
17 *  2) Redistributions in binary form must reproduce the above copyright notice,
18 *     this list of conditions and the following disclaimer in the documentation
19 *     and/or other materials provided with the distribution.
20 *
21 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 *     be used to endorse or promote products derived from this software without
23 *     specific prior written permission.
24 *
25 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 *  POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38 
39 #include "../inc/hw_types.h"
40 #include "../inc/hw_ccfg.h"
41 #include "flash.h"
42 #include "rom.h"
43 #include "chipinfo.h"
44 
45 //*****************************************************************************
46 //
47 // Handle support for DriverLib in ROM:
48 // This section will undo prototype renaming made in the header file
49 //
50 //*****************************************************************************
51 #if !defined(DOXYGEN)
52     #undef  FlashPowerModeSet
53     #define FlashPowerModeSet               NOROM_FlashPowerModeSet
54     #undef  FlashPowerModeGet
55     #define FlashPowerModeGet               NOROM_FlashPowerModeGet
56     #undef  FlashProtectionSet
57     #define FlashProtectionSet              NOROM_FlashProtectionSet
58     #undef  FlashProtectionGet
59     #define FlashProtectionGet              NOROM_FlashProtectionGet
60     #undef  FlashProtectionSave
61     #define FlashProtectionSave             NOROM_FlashProtectionSave
62     #undef  FlashSectorErase
63     #define FlashSectorErase                NOROM_FlashSectorErase
64     #undef  FlashProgram
65     #define FlashProgram                    NOROM_FlashProgram
66     #undef  FlashEfuseReadRow
67     #define FlashEfuseReadRow               NOROM_FlashEfuseReadRow
68     #undef  FlashDisableSectorsForWrite
69     #define FlashDisableSectorsForWrite     NOROM_FlashDisableSectorsForWrite
70 #endif
71 
72 
73 //*****************************************************************************
74 //
75 // Defines for accesses to the security control in the customer configuration
76 // area in flash top sector.
77 //
78 //*****************************************************************************
79 #define CCFG_OFFSET_SECURITY   CCFG_O_BL_CONFIG
80 #define CCFG_OFFSET_SECT_PROT  CCFG_O_CCFG_PROT_31_0
81 #define CCFG_SIZE_SECURITY     0x00000014
82 #define CCFG_SIZE_SECT_PROT    0x00000004
83 
84 //*****************************************************************************
85 //
86 // Default values for security control in customer configuration area in flash
87 // top sector.
88 //
89 //*****************************************************************************
90 const uint8_t g_pui8CcfgDefaultSec[] = {0xFF, 0xFF, 0xFF, 0xC5,
91                                         0xFF, 0xFF, 0xFF, 0xFF,
92                                         0xC5, 0xFF, 0xFF, 0xFF,
93                                         0xC5, 0xC5, 0xC5, 0xFF,
94                                         0xC5, 0xC5, 0xC5, 0xFF
95                                        };
96 
97 typedef uint32_t (* FlashPrgPointer_t) (uint8_t *, uint32_t, uint32_t);
98 
99 typedef uint32_t (* FlashSectorErasePointer_t) (uint32_t);
100 
101 //*****************************************************************************
102 //
103 // Function prototypes for static functions
104 //
105 //*****************************************************************************
106 static void SetReadMode(void);
107 
108 //*****************************************************************************
109 //
110 // Set power mode
111 //
112 //*****************************************************************************
113 void
FlashPowerModeSet(uint32_t ui32PowerMode,uint32_t ui32BankGracePeriod,uint32_t ui32PumpGracePeriod)114 FlashPowerModeSet(uint32_t ui32PowerMode, uint32_t ui32BankGracePeriod,
115                   uint32_t ui32PumpGracePeriod)
116 {
117     // Check the arguments.
118     ASSERT(ui32PowerMode == FLASH_PWR_ACTIVE_MODE ||
119            ui32PowerMode == FLASH_PWR_OFF_MODE    ||
120            ui32PowerMode == FLASH_PWR_DEEP_STDBY_MODE);
121     ASSERT(ui32BankGracePeriod <= 0xFF);
122     ASSERT(ui32PumpGracePeriod <= 0xFFFF);
123 
124     // Initialize flag requesting deprecated power mode
125     HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
126     HWREG(FLASH_BASE + FLASH_O_FWFLAG) &= ~FW_PWRMODE_DEPRECATED;
127     HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
128 
129     switch(ui32PowerMode)
130     {
131     case FLASH_PWR_ACTIVE_MODE:
132         // Set bank power mode to ACTIVE.
133         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
134             (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
135              ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_ACTIVE;
136 
137         // Set charge pump power mode to ACTIVE mode.
138         HWREG(FLASH_BASE + FLASH_O_FPAC1) =
139             (HWREG(FLASH_BASE + FLASH_O_FPAC1) & ~FLASH_FPAC1_PUMPPWR_M) | (1 << FLASH_FPAC1_PUMPPWR_S);
140         break;
141 
142     case FLASH_PWR_DEEP_STDBY_MODE:
143         // Deprecated power mode requested. Set flag.
144         HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;
145         HWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_PWRMODE_DEPRECATED;
146         HWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;
147         // Fall through to force FLASH_PWR_OFF_MODE power mode
148     case FLASH_PWR_OFF_MODE:
149         // Set bank grace period.
150         HWREG(FLASH_BASE + FLASH_O_FBAC) =
151             (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
152             ((ui32BankGracePeriod << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
153 
154         // Set pump grace period.
155         HWREG(FLASH_BASE + FLASH_O_FPAC2) =
156             (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
157             ((ui32PumpGracePeriod << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
158 
159         // Set bank power mode to SLEEP.
160         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &= ~FLASH_FBFALLBACK_BANKPWR0_M;
161 
162         // Set charge pump power mode to SLEEP mode.
163         HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
164         break;
165     }
166 }
167 
168 //*****************************************************************************
169 //
170 // Get current configured power mode
171 //
172 //*****************************************************************************
173 uint32_t
FlashPowerModeGet(void)174 FlashPowerModeGet(void)
175 {
176     uint32_t ui32PowerMode;
177     uint32_t ui32BankPwrMode;
178 
179     ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
180                       FLASH_FBFALLBACK_BANKPWR0_M;
181 
182     if((ui32BankPwrMode == FBFALLBACK_SLEEP) &&
183        ((HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_PWRMODE_DEPRECATED) == FW_PWRMODE_DEPRECATED))
184     {
185         ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
186     }
187     else if((ui32BankPwrMode == FBFALLBACK_SLEEP) &&
188             ((HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_PWRMODE_DEPRECATED) == 0))
189     {
190         ui32PowerMode = FLASH_PWR_OFF_MODE;
191     }
192     else
193     {
194         ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
195     }
196 
197     // Return power mode.
198     return(ui32PowerMode);
199 }
200 
201 //*****************************************************************************
202 //
203 // Set sector protection
204 //
205 //*****************************************************************************
206 void
FlashProtectionSet(uint32_t ui32SectorAddress,uint32_t ui32ProtectMode)207 FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
208 {
209     uint32_t ui32SectorNumber;
210 
211     // Check the arguments.
212     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
213                                  FlashSectorSizeGet()));
214     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
215 
216     if(ui32ProtectMode == FLASH_WRITE_PROTECT)
217     {
218         ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
219                            FlashSectorSizeGet();
220         HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
221 
222         if(ui32SectorNumber <= 31)
223         {
224             HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
225             HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
226         }
227         else if(ui32SectorNumber <= 63)
228         {
229             HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
230                 (1 << (ui32SectorNumber & 0x1F));
231             HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
232                 (1 << (ui32SectorNumber & 0x1F));
233         }
234 
235         HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
236     }
237 }
238 
239 //*****************************************************************************
240 //
241 // Get sector protection
242 //
243 //*****************************************************************************
244 uint32_t
FlashProtectionGet(uint32_t ui32SectorAddress)245 FlashProtectionGet(uint32_t ui32SectorAddress)
246 {
247     uint32_t ui32SectorProtect;
248     uint32_t ui32SectorNumber;
249 
250     // Check the arguments.
251     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
252                                  FlashSectorSizeGet()));
253     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
254 
255     ui32SectorProtect = FLASH_NO_PROTECT;
256     ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
257 
258     if(ui32SectorNumber <= 31)
259     {
260         if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
261                 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
262         {
263             ui32SectorProtect = FLASH_WRITE_PROTECT;
264         }
265     }
266     else if(ui32SectorNumber <= 63)
267     {
268         if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
269                 (1 << (ui32SectorNumber & 0x1F))) &&
270                 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
271                  (1 << (ui32SectorNumber & 0x1F))))
272         {
273             ui32SectorProtect = FLASH_WRITE_PROTECT;
274         }
275     }
276 
277     return(ui32SectorProtect);
278 }
279 
280 //*****************************************************************************
281 //
282 // Save sector protection to make it permanent
283 //
284 //*****************************************************************************
285 uint32_t
FlashProtectionSave(uint32_t ui32SectorAddress)286 FlashProtectionSave(uint32_t ui32SectorAddress)
287 {
288     uint32_t ui32ErrorReturn;
289     uint32_t ui32SectorNumber;
290     uint32_t ui32CcfgSectorAddr;
291     uint32_t ui32ProgBuf;
292 
293     ui32ErrorReturn = FAPI_STATUS_SUCCESS;
294 
295     // Check the arguments.
296     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
297                                  FlashSectorSizeGet()));
298     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
299 
300     if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
301     {
302         // Find sector number for specified sector.
303         ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
304         ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
305 
306         // Adjust CCFG address to the 32-bit CCFG word holding the
307         // protect-bit for the specified sector.
308         ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
309 
310         // Find value to program by setting the protect-bit which
311         // corresponds to specified sector number, to 0.
312         // Leave other protect-bits unchanged.
313         ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
314                                    *(uint32_t *)ui32CcfgSectorAddr;
315 
316         ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr,
317                                        CCFG_SIZE_SECT_PROT);
318     }
319 
320     // Return status.
321     return(ui32ErrorReturn);
322 }
323 
324 //*****************************************************************************
325 //
326 // Erase a flash sector
327 //
328 //*****************************************************************************
329 uint32_t
FlashSectorErase(uint32_t ui32SectorAddress)330 FlashSectorErase(uint32_t ui32SectorAddress)
331 {
332     uint32_t ui32ErrorReturn;
333     FlashSectorErasePointer_t FuncPointer;
334 
335     // Check the arguments.
336     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
337                                  FlashSectorSizeGet()));
338     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
339 
340     // Call ROM function that handles the actual erase operation
341     FuncPointer = (uint32_t (*)(uint32_t)) (ROM_API_FLASH_TABLE[5]);
342     ui32ErrorReturn = FuncPointer(ui32SectorAddress);
343 
344     // Enable standby in flash bank since ROM function might have disabled it
345     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
346 
347     // Return status of operation.
348     return(ui32ErrorReturn);
349 
350 }
351 
352 
353 //*****************************************************************************
354 //
355 // Programs unprotected main bank flash sectors
356 //
357 //*****************************************************************************
358 uint32_t
FlashProgram(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)359 FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
360 {
361     uint32_t ui32ErrorReturn;
362     FlashPrgPointer_t FuncPointer;
363 
364     // Check the arguments.
365     ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
366 
367     // Call ROM function that handles the actual program operation
368     FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ROM_API_FLASH_TABLE[6]);
369     ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
370 
371     // Enable standby in flash bank since ROM function might have disabled it
372     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
373 
374     // Return status of operation.
375     return(ui32ErrorReturn);
376 
377 }
378 
379 //*****************************************************************************
380 //
381 // Reads efuse data from specified row
382 //
383 //*****************************************************************************
384 bool
FlashEfuseReadRow(uint32_t * pui32EfuseData,uint32_t ui32RowAddress)385 FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
386 {
387     bool bStatus;
388 
389     // Make sure the clock for the efuse is enabled
390     HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
391 
392     // Set timing for EFUSE read operations.
393     HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
394             FLASH_EFUSEREAD_READCLOCK_M);
395 
396     // Clear status register.
397     HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
398 
399     // Select the FuseROM block 0.
400     HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
401 
402     // Start the read operation.
403     HWREG(FLASH_BASE + FLASH_O_EFUSE) =
404         (DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
405         (ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
406 
407     // Wait for operation to finish.
408     while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
409     {
410     }
411 
412     // Check if error reported.
413     if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
414     {
415         // Set error status.
416         bStatus = 1;
417 
418         // Clear data.
419         *pui32EfuseData = 0;
420     }
421     else
422     {
423         // Set ok status.
424         bStatus = 0;
425 
426         // No error. Get data from data register.
427         *pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
428     }
429 
430     // Disable the efuse clock to conserve power
431     HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
432 
433     // Return the data.
434     return(bStatus);
435 }
436 
437 
438 //*****************************************************************************
439 //
440 // Disables all sectors for erase and programming on the active bank
441 //
442 //*****************************************************************************
443 void
FlashDisableSectorsForWrite(void)444 FlashDisableSectorsForWrite(void)
445 {
446     // Configure flash back to read mode
447     SetReadMode();
448 
449     // Disable Level 1 Protection.
450     HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
451 
452     // Disable all sectors for erase and programming.
453     HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
454 
455     // Enable Level 1 Protection.
456     HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
457 
458     // Protect sectors from sector erase.
459     HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
460     HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
461     HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
462     HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
463 }
464 
465 //*****************************************************************************
466 //
467 //! \internal
468 //! Used to set flash in read mode.
469 //!
470 //! Flash is configured with values loaded from OTP dependent on the current
471 //! regulator mode.
472 //!
473 //! \return None.
474 //
475 //*****************************************************************************
476 static void
SetReadMode(void)477 SetReadMode(void)
478 {
479     uint32_t ui32TrimValue;
480     uint32_t ui32Value;
481 
482     // Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
483     // VIN_AT_X and VIN_BY_PASS for read mode
484     if(HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
485        AON_PMCTL_PWRCTL_EXT_REG_MODE)
486     {
487         // Select trim values for external regulator mode:
488         // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
489         // COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 6:5)
490         // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
491         HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
492 
493         ui32TrimValue =
494            HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
495 
496         ui32Value = ((ui32TrimValue &
497                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
498                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
499                     FLASH_CFG_STANDBY_MODE_SEL_S;
500 
501         ui32Value |= ((ui32TrimValue &
502                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
503                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
504                      FLASH_CFG_STANDBY_PW_SEL_S;
505 
506         // Configure DIS_STANDBY (OTP offset 0x308 bit 4).
507         // Configure DIS_IDLE    (OTP offset 0x308 bit 3).
508         ui32Value |= ((ui32TrimValue &
509                        (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
510                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
511                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
512                         FLASH_CFG_DIS_IDLE_S;
513 
514         HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
515                                            ~(FLASH_CFG_STANDBY_MODE_SEL_M |
516                                              FLASH_CFG_STANDBY_PW_SEL_M   |
517                                              FLASH_CFG_DIS_STANDBY_M      |
518                                              FLASH_CFG_DIS_IDLE_M)) | ui32Value;
519 
520         // Check if sample and hold functionality is disabled.
521         if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
522         {
523             // Wait for disabled sample and hold functionality to be stable.
524             while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
525             {
526             }
527         }
528 
529         // Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
530         ui32Value = ((ui32TrimValue &
531                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
532                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
533                     FLASH_FSEQPMP_VIN_AT_X_S;
534 
535         // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
536         // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
537         // VIN_BY_PASS should be 1
538         if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
539             FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
540         {
541             ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
542         }
543 
544         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
545         HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
546                                     (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
547                                      ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
548                                        FLASH_FSEQPMP_VIN_AT_X_M))  | ui32Value;
549         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
550     }
551     else
552     {
553         // Select trim values for internal regulator mode:
554         // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
555         // COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 14:13)
556         // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
557         HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
558 
559         ui32TrimValue =
560            HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
561 
562         ui32Value = ((ui32TrimValue &
563                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
564                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
565                     FLASH_CFG_STANDBY_MODE_SEL_S;
566 
567         ui32Value |= ((ui32TrimValue &
568                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
569                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
570                      FLASH_CFG_STANDBY_PW_SEL_S;
571 
572         // Configure DIS_STANDBY (OTP offset 0x308 bit 12).
573         // Configure DIS_IDLE    (OTP offset 0x308 bit 11).
574         ui32Value |= ((ui32TrimValue &
575                        (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
576                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
577                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
578                         FLASH_CFG_DIS_IDLE_S;
579 
580         HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
581                                            ~(FLASH_CFG_STANDBY_MODE_SEL_M |
582                                              FLASH_CFG_STANDBY_PW_SEL_M   |
583                                              FLASH_CFG_DIS_STANDBY_M      |
584                                              FLASH_CFG_DIS_IDLE_M)) | ui32Value;
585 
586         // Check if sample and hold functionality is disabled.
587         if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
588         {
589             // Wait for disabled sample and hold functionality to be stable.
590             while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
591             {
592             }
593         }
594 
595         // Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
596         ui32Value = (((ui32TrimValue &
597                        FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
598                        FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
599                        FLASH_FSEQPMP_VIN_AT_X_S);
600 
601         // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
602         // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
603         // VIN_BY_PASS should be 1
604         if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
605             FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
606         {
607             ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
608         }
609 
610         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
611         HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
612                                     (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
613                                      ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
614                                        FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
615         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
616     }
617 }
618 
619 //*****************************************************************************
620 //
621 // HAPI Flash program function
622 //
623 //*****************************************************************************
624 uint32_t
MemBusWrkAroundHapiProgramFlash(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)625 MemBusWrkAroundHapiProgramFlash(uint8_t *pui8DataBuffer, uint32_t ui32Address,
626                                 uint32_t ui32Count)
627 {
628     uint32_t ui32ErrorReturn;
629     FlashPrgPointer_t FuncPointer;
630     uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (5 * 4));
631 
632     // Call ROM function
633     FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ui32RomAddr);
634     ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
635 
636     // Enable standby in flash bank since ROM function might have disabled it
637     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
638 
639     // Return status of operation.
640     return(ui32ErrorReturn);
641 }
642 
643 //*****************************************************************************
644 //
645 // HAPI Flash sector erase function
646 //
647 //*****************************************************************************
648 uint32_t
MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)649 MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)
650 {
651     uint32_t ui32ErrorReturn;
652 
653     FlashSectorErasePointer_t FuncPointer;
654     uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (3 * 4));
655 
656     // Call ROM function
657     FuncPointer = (uint32_t (*)(uint32_t)) (ui32RomAddr);
658     ui32ErrorReturn = FuncPointer(ui32Address);
659 
660     // Enable standby in flash bank since ROM function might have disabled it
661     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
662 
663     // Return status of operation.
664     return(ui32ErrorReturn);
665 }
666