1 /******************************************************************************
2 *  Filename:       flash.c
3 *  Revised:        2020-02-14 11:30:20 +0100 (Fri, 14 Feb 2020)
4 *  Revision:       56760
5 *
6 *  Description:    Driver for on chip Flash.
7 *
8 *  Copyright (c) 2015 - 2017, 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     switch(ui32PowerMode)
125     {
126     case FLASH_PWR_ACTIVE_MODE:
127         // Set bank power mode to ACTIVE.
128         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
129             (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
130              ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_ACTIVE;
131 
132         // Set charge pump power mode to ACTIVE mode.
133         HWREG(FLASH_BASE + FLASH_O_FPAC1) =
134             (HWREG(FLASH_BASE + FLASH_O_FPAC1) & ~FLASH_FPAC1_PUMPPWR_M) | (1 << FLASH_FPAC1_PUMPPWR_S);
135         break;
136 
137     case FLASH_PWR_OFF_MODE:
138         // Set bank grace period.
139         HWREG(FLASH_BASE + FLASH_O_FBAC) =
140             (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
141             ((ui32BankGracePeriod << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
142 
143         // Set pump grace period.
144         HWREG(FLASH_BASE + FLASH_O_FPAC2) =
145             (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
146             ((ui32PumpGracePeriod << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
147 
148         // Set bank power mode to SLEEP.
149         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &= ~FLASH_FBFALLBACK_BANKPWR0_M;
150 
151         // Set charge pump power mode to SLEEP mode.
152         HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
153         break;
154 
155     case FLASH_PWR_DEEP_STDBY_MODE:
156         // Set bank grace period.
157         HWREG(FLASH_BASE + FLASH_O_FBAC) =
158             (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
159             ((ui32BankGracePeriod << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
160 
161         // Set pump grace period.
162         HWREG(FLASH_BASE + FLASH_O_FPAC2) =
163             (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
164             ((ui32PumpGracePeriod << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
165 
166         // Set bank power mode to DEEP STANDBY mode.
167         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
168             (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
169              ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_DEEP_STDBY;
170 
171         // Set charge pump power mode to STANDBY mode.
172         HWREG(FLASH_BASE + FLASH_O_FPAC1) |= FLASH_FPAC1_PUMPPWR_M;
173         break;
174     }
175 }
176 
177 //*****************************************************************************
178 //
179 // Get current configured power mode
180 //
181 //*****************************************************************************
182 uint32_t
FlashPowerModeGet(void)183 FlashPowerModeGet(void)
184 {
185     uint32_t ui32PowerMode;
186     uint32_t ui32BankPwrMode;
187 
188     ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
189                       FLASH_FBFALLBACK_BANKPWR0_M;
190 
191     if(ui32BankPwrMode == FBFALLBACK_SLEEP)
192     {
193         ui32PowerMode = FLASH_PWR_OFF_MODE;
194     }
195     else if(ui32BankPwrMode == FBFALLBACK_DEEP_STDBY)
196     {
197         ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
198     }
199     else
200     {
201         ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
202     }
203 
204     // Return power mode.
205     return(ui32PowerMode);
206 }
207 
208 //*****************************************************************************
209 //
210 // Set sector protection
211 //
212 //*****************************************************************************
213 void
FlashProtectionSet(uint32_t ui32SectorAddress,uint32_t ui32ProtectMode)214 FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
215 {
216     uint32_t ui32SectorNumber;
217 
218     // Check the arguments.
219     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
220                                  FlashSectorSizeGet()));
221     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
222 
223     if(ui32ProtectMode == FLASH_WRITE_PROTECT)
224     {
225         ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
226                            FlashSectorSizeGet();
227         HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
228 
229         if(ui32SectorNumber <= 31)
230         {
231             HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
232             HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
233         }
234         else if(ui32SectorNumber <= 63)
235         {
236             HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
237                 (1 << (ui32SectorNumber & 0x1F));
238             HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
239                 (1 << (ui32SectorNumber & 0x1F));
240         }
241 
242         HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
243     }
244 }
245 
246 //*****************************************************************************
247 //
248 // Get sector protection
249 //
250 //*****************************************************************************
251 uint32_t
FlashProtectionGet(uint32_t ui32SectorAddress)252 FlashProtectionGet(uint32_t ui32SectorAddress)
253 {
254     uint32_t ui32SectorProtect;
255     uint32_t ui32SectorNumber;
256 
257     // Check the arguments.
258     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
259                                  FlashSectorSizeGet()));
260     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
261 
262     ui32SectorProtect = FLASH_NO_PROTECT;
263     ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
264 
265     if(ui32SectorNumber <= 31)
266     {
267         if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
268                 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
269         {
270             ui32SectorProtect = FLASH_WRITE_PROTECT;
271         }
272     }
273     else if(ui32SectorNumber <= 63)
274     {
275         if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
276                 (1 << (ui32SectorNumber & 0x1F))) &&
277                 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
278                  (1 << (ui32SectorNumber & 0x1F))))
279         {
280             ui32SectorProtect = FLASH_WRITE_PROTECT;
281         }
282     }
283 
284     return(ui32SectorProtect);
285 }
286 
287 //*****************************************************************************
288 //
289 // Save sector protection to make it permanent
290 //
291 //*****************************************************************************
292 uint32_t
FlashProtectionSave(uint32_t ui32SectorAddress)293 FlashProtectionSave(uint32_t ui32SectorAddress)
294 {
295     uint32_t ui32ErrorReturn;
296     uint32_t ui32SectorNumber;
297     uint32_t ui32CcfgSectorAddr;
298     uint32_t ui32ProgBuf;
299 
300     ui32ErrorReturn = FAPI_STATUS_SUCCESS;
301 
302     // Check the arguments.
303     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
304                                  FlashSectorSizeGet()));
305     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
306 
307     if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
308     {
309         // Find sector number for specified sector.
310         ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
311         ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
312 
313         // Adjust CCFG address to the 32-bit CCFG word holding the
314         // protect-bit for the specified sector.
315         ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
316 
317         // Find value to program by setting the protect-bit which
318         // corresponds to specified sector number, to 0.
319         // Leave other protect-bits unchanged.
320         ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
321                                    *(uint32_t *)ui32CcfgSectorAddr;
322 
323         ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr,
324                                        CCFG_SIZE_SECT_PROT);
325     }
326 
327     // Return status.
328     return(ui32ErrorReturn);
329 }
330 
331 //*****************************************************************************
332 //
333 // Erase a flash sector
334 //
335 //*****************************************************************************
336 uint32_t
FlashSectorErase(uint32_t ui32SectorAddress)337 FlashSectorErase(uint32_t ui32SectorAddress)
338 {
339     uint32_t ui32ErrorReturn;
340     FlashSectorErasePointer_t FuncPointer;
341 
342     // Check the arguments.
343     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
344                                  FlashSectorSizeGet()));
345     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
346 
347     // Call ROM function that handles the actual erase operation
348     FuncPointer = (uint32_t (*)(uint32_t)) (ROM_API_FLASH_TABLE[5]);
349     ui32ErrorReturn = FuncPointer(ui32SectorAddress);
350 
351     // Enable standby in flash bank since ROM function might have disabled it
352     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
353 
354     // Return status of operation.
355     return(ui32ErrorReturn);
356 
357 }
358 
359 
360 //*****************************************************************************
361 //
362 // Programs unprotected main bank flash sectors
363 //
364 //*****************************************************************************
365 uint32_t
FlashProgram(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)366 FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
367 {
368     uint32_t ui32ErrorReturn;
369     FlashPrgPointer_t FuncPointer;
370 
371     // Check the arguments.
372     ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
373 
374     // Call ROM function that handles the actual program operation
375     FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ROM_API_FLASH_TABLE[6]);
376     ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
377 
378     // Enable standby in flash bank since ROM function might have disabled it
379     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
380 
381     // Return status of operation.
382     return(ui32ErrorReturn);
383 
384 }
385 
386 //*****************************************************************************
387 //
388 // Reads efuse data from specified row
389 //
390 //*****************************************************************************
391 bool
FlashEfuseReadRow(uint32_t * pui32EfuseData,uint32_t ui32RowAddress)392 FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
393 {
394     bool bStatus;
395 
396     // Make sure the clock for the efuse is enabled
397     HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
398 
399     // Set timing for EFUSE read operations.
400     HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
401             FLASH_EFUSEREAD_READCLOCK_M);
402 
403     // Clear status register.
404     HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
405 
406     // Select the FuseROM block 0.
407     HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
408 
409     // Start the read operation.
410     HWREG(FLASH_BASE + FLASH_O_EFUSE) =
411         (DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
412         (ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
413 
414     // Wait for operation to finish.
415     while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
416     {
417     }
418 
419     // Check if error reported.
420     if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
421     {
422         // Set error status.
423         bStatus = 1;
424 
425         // Clear data.
426         *pui32EfuseData = 0;
427     }
428     else
429     {
430         // Set ok status.
431         bStatus = 0;
432 
433         // No error. Get data from data register.
434         *pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
435     }
436 
437     // Disable the efuse clock to conserve power
438     HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
439 
440     // Return the data.
441     return(bStatus);
442 }
443 
444 
445 //*****************************************************************************
446 //
447 // Disables all sectors for erase and programming on the active bank
448 //
449 //*****************************************************************************
450 void
FlashDisableSectorsForWrite(void)451 FlashDisableSectorsForWrite(void)
452 {
453     // Configure flash back to read mode
454     SetReadMode();
455 
456     // Disable Level 1 Protection.
457     HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
458 
459     // Disable all sectors for erase and programming.
460     HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
461 
462     // Enable Level 1 Protection.
463     HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
464 
465     // Protect sectors from sector erase.
466     HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
467     HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
468     HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
469     HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
470 }
471 
472 //*****************************************************************************
473 //
474 //! \internal
475 //! Used to set flash in read mode.
476 //!
477 //! Flash is configured with values loaded from OTP dependent on the current
478 //! regulator mode.
479 //!
480 //! \return None.
481 //
482 //*****************************************************************************
483 static void
SetReadMode(void)484 SetReadMode(void)
485 {
486     uint32_t ui32TrimValue;
487     uint32_t ui32Value;
488 
489     // Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
490     // VIN_AT_X and VIN_BY_PASS for read mode
491     if(HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &
492        AON_PMCTL_PWRCTL_EXT_REG_MODE)
493     {
494         // Select trim values for external regulator mode:
495         // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
496         // COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 6:5)
497         // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
498         HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
499 
500         ui32TrimValue =
501            HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
502 
503         ui32Value = ((ui32TrimValue &
504                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
505                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
506                     FLASH_CFG_STANDBY_MODE_SEL_S;
507 
508         ui32Value |= ((ui32TrimValue &
509                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
510                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
511                      FLASH_CFG_STANDBY_PW_SEL_S;
512 
513         // Configure DIS_STANDBY (OTP offset 0x308 bit 4).
514         // Configure DIS_IDLE    (OTP offset 0x308 bit 3).
515         ui32Value |= ((ui32TrimValue &
516                        (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
517                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
518                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
519                         FLASH_CFG_DIS_IDLE_S;
520 
521         HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
522                                            ~(FLASH_CFG_STANDBY_MODE_SEL_M |
523                                              FLASH_CFG_STANDBY_PW_SEL_M   |
524                                              FLASH_CFG_DIS_STANDBY_M      |
525                                              FLASH_CFG_DIS_IDLE_M)) | ui32Value;
526 
527         // Check if sample and hold functionality is disabled.
528         if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
529         {
530             // Wait for disabled sample and hold functionality to be stable.
531             while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
532             {
533             }
534         }
535 
536         // Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
537         ui32Value = ((ui32TrimValue &
538                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
539                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
540                     FLASH_FSEQPMP_VIN_AT_X_S;
541 
542         // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
543         // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
544         // VIN_BY_PASS should be 1
545         if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
546             FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
547         {
548             ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
549         }
550 
551         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
552         HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
553                                     (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
554                                      ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
555                                        FLASH_FSEQPMP_VIN_AT_X_M))  | ui32Value;
556         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
557     }
558     else
559     {
560         // Select trim values for internal regulator mode:
561         // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
562         // COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 14:13)
563         // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
564         HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
565 
566         ui32TrimValue =
567            HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
568 
569         ui32Value = ((ui32TrimValue &
570                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
571                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
572                     FLASH_CFG_STANDBY_MODE_SEL_S;
573 
574         ui32Value |= ((ui32TrimValue &
575                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
576                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
577                      FLASH_CFG_STANDBY_PW_SEL_S;
578 
579         // Configure DIS_STANDBY (OTP offset 0x308 bit 12).
580         // Configure DIS_IDLE    (OTP offset 0x308 bit 11).
581         ui32Value |= ((ui32TrimValue &
582                        (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
583                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
584                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
585                         FLASH_CFG_DIS_IDLE_S;
586 
587         HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
588                                            ~(FLASH_CFG_STANDBY_MODE_SEL_M |
589                                              FLASH_CFG_STANDBY_PW_SEL_M   |
590                                              FLASH_CFG_DIS_STANDBY_M      |
591                                              FLASH_CFG_DIS_IDLE_M)) | ui32Value;
592 
593         // Check if sample and hold functionality is disabled.
594         if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
595         {
596             // Wait for disabled sample and hold functionality to be stable.
597             while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
598             {
599             }
600         }
601 
602         // Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
603         ui32Value = (((ui32TrimValue &
604                        FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
605                        FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
606                        FLASH_FSEQPMP_VIN_AT_X_S);
607 
608         // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
609         // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
610         // VIN_BY_PASS should be 1
611         if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
612             FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
613         {
614             ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
615         }
616 
617         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
618         HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
619                                     (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
620                                      ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
621                                        FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
622         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
623     }
624 }
625 
626 //*****************************************************************************
627 //
628 // HAPI Flash program function
629 //
630 //*****************************************************************************
631 uint32_t
MemBusWrkAroundHapiProgramFlash(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)632 MemBusWrkAroundHapiProgramFlash(uint8_t *pui8DataBuffer, uint32_t ui32Address,
633                                 uint32_t ui32Count)
634 {
635     uint32_t ui32ErrorReturn;
636     FlashPrgPointer_t FuncPointer;
637     uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (5 * 4));
638 
639     // Call ROM function
640     FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ui32RomAddr);
641     ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
642 
643     // Enable standby in flash bank since ROM function might have disabled it
644     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
645 
646     // Return status of operation.
647     return(ui32ErrorReturn);
648 }
649 
650 //*****************************************************************************
651 //
652 // HAPI Flash sector erase function
653 //
654 //*****************************************************************************
655 uint32_t
MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)656 MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)
657 {
658     uint32_t ui32ErrorReturn;
659 
660     FlashSectorErasePointer_t FuncPointer;
661     uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (3 * 4));
662 
663     // Call ROM function
664     FuncPointer = (uint32_t (*)(uint32_t)) (ui32RomAddr);
665     ui32ErrorReturn = FuncPointer(ui32Address);
666 
667     // Enable standby in flash bank since ROM function might have disabled it
668     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
669 
670     // Return status of operation.
671     return(ui32ErrorReturn);
672 }
673