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