1 /******************************************************************************
2 *  Filename:       flash.c
3 *  Revised:        2015-11-02 14:35:00 +0100 (Mon, 02 Nov 2015)
4 *  Revision:       44906
5 *
6 *  Description:    Driver for on chip Flash.
7 *
8 *  Copyright (c) 2015, 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 <driverlib/flash.h>
41 #include <driverlib/rom.h>
42 #include <driverlib/chipinfo.h>
43 
44 //*****************************************************************************
45 //
46 // Handle support for DriverLib in ROM:
47 // This section will undo prototype renaming made in the header file
48 //
49 //*****************************************************************************
50 #if !defined(DOXYGEN)
51     #undef  FlashPowerModeSet
52     #define FlashPowerModeSet               NOROM_FlashPowerModeSet
53     #undef  FlashPowerModeGet
54     #define FlashPowerModeGet               NOROM_FlashPowerModeGet
55     #undef  FlashProtectionSet
56     #define FlashProtectionSet              NOROM_FlashProtectionSet
57     #undef  FlashProtectionGet
58     #define FlashProtectionGet              NOROM_FlashProtectionGet
59     #undef  FlashProtectionSave
60     #define FlashProtectionSave             NOROM_FlashProtectionSave
61     #undef  FlashSectorErase
62     #define FlashSectorErase                NOROM_FlashSectorErase
63     #undef  FlashProgram
64     #define FlashProgram                    NOROM_FlashProgram
65     #undef  FlashEfuseReadRow
66     #define FlashEfuseReadRow               NOROM_FlashEfuseReadRow
67     #undef  FlashDisableSectorsForWrite
68     #define FlashDisableSectorsForWrite     NOROM_FlashDisableSectorsForWrite
69 #endif
70 
71 //*****************************************************************************
72 //
73 // Default values for security control in customer configuration area in flash
74 // top sector.
75 //
76 //*****************************************************************************
77 const uint8_t g_pui8CcfgDefaultSec[] = {0xFF, 0xFF, 0xFF, 0xC5,
78                                         0xFF, 0xFF, 0xFF, 0xFF,
79                                         0xC5, 0xFF, 0xFF, 0xFF,
80                                         0xC5, 0xC5, 0xC5, 0xFF,
81                                         0xC5, 0xC5, 0xC5, 0xFF
82                                        };
83 
84 typedef uint32_t (* FlashPrgPointer_t) (uint8_t *, uint32_t, uint32_t);
85 
86 typedef uint32_t (* FlashSectorErasePointer_t) (uint32_t);
87 
88 //*****************************************************************************
89 //
90 // Function prototypes for static functions
91 //
92 //*****************************************************************************
93 static void SetReadMode(void);
94 
95 //*****************************************************************************
96 //
97 //! Set power mode
98 //
99 //*****************************************************************************
100 void
FlashPowerModeSet(uint32_t ui32PowerMode,uint32_t ui32BankGracePeriode,uint32_t ui32PumpGracePeriode)101 FlashPowerModeSet(uint32_t ui32PowerMode, uint32_t ui32BankGracePeriode,
102                   uint32_t ui32PumpGracePeriode)
103 {
104     //
105     // Check the arguments.
106     //
107     ASSERT(ui32PowerMode == FLASH_PWR_ACTIVE_MODE ||
108            ui32PowerMode == FLASH_PWR_OFF_MODE    ||
109            ui32PowerMode == FLASH_PWR_DEEP_STDBY_MODE);
110     ASSERT(ui32BankGracePeriode <= 0xFF);
111     ASSERT(ui32PumpGracePeriode <= 0xFFFF);
112 
113     switch(ui32PowerMode)
114     {
115     case FLASH_PWR_ACTIVE_MODE:
116         //
117         // Set bank power mode to ACTIVE.
118         //
119         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
120             (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
121              ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_ACTIVE;
122 
123         //
124         // Set charge pump power mode to ACTIVE mode.
125         //
126         HWREG(FLASH_BASE + FLASH_O_FPAC1) =
127             (HWREG(FLASH_BASE + FLASH_O_FPAC1) & ~FLASH_FPAC1_PUMPPWR_M) | (1 << FLASH_FPAC1_PUMPPWR_S);
128         break;
129 
130     case FLASH_PWR_OFF_MODE:
131         //
132         // Set bank grace periode.
133         //
134         HWREG(FLASH_BASE + FLASH_O_FBAC) =
135             (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
136             ((ui32BankGracePeriode << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
137 
138         //
139         // Set pump grace periode.
140         //
141         HWREG(FLASH_BASE + FLASH_O_FPAC2) =
142             (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
143             ((ui32PumpGracePeriode << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
144 
145         //
146         // Set bank power mode to SLEEP.
147         //
148         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &= ~FLASH_FBFALLBACK_BANKPWR0_M;
149 
150         //
151         // Set charge pump power mode to SLEEP mode.
152         //
153         HWREG(FLASH_BASE + FLASH_O_FPAC1) &= ~FLASH_FPAC1_PUMPPWR_M;
154         break;
155 
156     case FLASH_PWR_DEEP_STDBY_MODE:
157         //
158         // Set bank grace periode.
159         //
160         HWREG(FLASH_BASE + FLASH_O_FBAC) =
161             (HWREG(FLASH_BASE + FLASH_O_FBAC) & (~FLASH_FBAC_BAGP_M)) |
162             ((ui32BankGracePeriode << FLASH_FBAC_BAGP_S) & FLASH_FBAC_BAGP_M);
163 
164         //
165         // Set pump grace periode.
166         //
167         HWREG(FLASH_BASE + FLASH_O_FPAC2) =
168             (HWREG(FLASH_BASE + FLASH_O_FPAC2) & (~FLASH_FPAC2_PAGP_M)) |
169             ((ui32PumpGracePeriode << FLASH_FPAC2_PAGP_S) & FLASH_FPAC2_PAGP_M);
170 
171         //
172         // Set bank power mode to DEEP STANDBY mode.
173         //
174         HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) =
175             (HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
176              ~FLASH_FBFALLBACK_BANKPWR0_M) | FBFALLBACK_DEEP_STDBY;
177 
178         //
179         // Set charge pump power mode to STANDBY mode.
180         //
181         HWREG(FLASH_BASE + FLASH_O_FPAC1) |= FLASH_FPAC1_PUMPPWR_M;
182         break;
183     }
184 }
185 
186 //*****************************************************************************
187 //
188 //! Get current configured power mode
189 //
190 //*****************************************************************************
191 uint32_t
FlashPowerModeGet(void)192 FlashPowerModeGet(void)
193 {
194     uint32_t ui32PowerMode;
195     uint32_t ui32BankPwrMode;
196 
197     ui32BankPwrMode = HWREG(FLASH_BASE + FLASH_O_FBFALLBACK) &
198                       FLASH_FBFALLBACK_BANKPWR0_M;
199 
200     if(ui32BankPwrMode == FBFALLBACK_SLEEP)
201     {
202         ui32PowerMode = FLASH_PWR_OFF_MODE;
203     }
204     else if(ui32BankPwrMode == FBFALLBACK_DEEP_STDBY)
205     {
206         ui32PowerMode = FLASH_PWR_DEEP_STDBY_MODE;
207     }
208     else
209     {
210         ui32PowerMode = FLASH_PWR_ACTIVE_MODE;
211     }
212 
213     //
214     // Return power mode.
215     //
216     return(ui32PowerMode);
217 }
218 
219 //*****************************************************************************
220 //
221 //! Set sector protection
222 //
223 //*****************************************************************************
224 void
FlashProtectionSet(uint32_t ui32SectorAddress,uint32_t ui32ProtectMode)225 FlashProtectionSet(uint32_t ui32SectorAddress, uint32_t ui32ProtectMode)
226 {
227     uint32_t ui32SectorNumber;
228 
229     //
230     // Check the arguments.
231     //
232     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
233                                  FlashSectorSizeGet()));
234     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
235 
236     if(ui32ProtectMode == FLASH_WRITE_PROTECT)
237     {
238         ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) /
239                            FlashSectorSizeGet();
240         HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
241 
242         if(ui32SectorNumber <= 31)
243         {
244             HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) |= (1 << ui32SectorNumber);
245             HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) |= (1 << ui32SectorNumber);
246         }
247         else if(ui32SectorNumber <= 63)
248         {
249             HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) |=
250                 (1 << (ui32SectorNumber & 0x1F));
251             HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) |=
252                 (1 << (ui32SectorNumber & 0x1F));
253         }
254 
255         HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
256     }
257 }
258 
259 //*****************************************************************************
260 //
261 //! Get sector protection
262 //
263 //*****************************************************************************
264 uint32_t
FlashProtectionGet(uint32_t ui32SectorAddress)265 FlashProtectionGet(uint32_t ui32SectorAddress)
266 {
267     uint32_t ui32SectorProtect;
268     uint32_t ui32SectorNumber;
269 
270     //
271     // Check the arguments.
272     //
273     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
274                                  FlashSectorSizeGet()));
275     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
276 
277     ui32SectorProtect = FLASH_NO_PROTECT;
278     ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
279 
280     if(ui32SectorNumber <= 31)
281     {
282         if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE0) & (1 << ui32SectorNumber)) &&
283                 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP0) & (1 << ui32SectorNumber)))
284         {
285             ui32SectorProtect = FLASH_WRITE_PROTECT;
286         }
287     }
288     else if(ui32SectorNumber <= 63)
289     {
290         if((HWREG(FLASH_BASE + FLASH_O_FSM_BSLE1) &
291                 (1 << (ui32SectorNumber & 0x1F))) &&
292                 (HWREG(FLASH_BASE + FLASH_O_FSM_BSLP1) &
293                  (1 << (ui32SectorNumber & 0x1F))))
294         {
295             ui32SectorProtect = FLASH_WRITE_PROTECT;
296         }
297     }
298 
299     return(ui32SectorProtect);
300 }
301 
302 //*****************************************************************************
303 //
304 //! Save sector protection to make it permanent
305 //
306 //*****************************************************************************
307 uint32_t
FlashProtectionSave(uint32_t ui32SectorAddress)308 FlashProtectionSave(uint32_t ui32SectorAddress)
309 {
310     uint32_t ui32ErrorReturn;
311     uint32_t ui32SectorNumber;
312     uint32_t ui32CcfgSectorAddr;
313     uint32_t ui32ProgBuf;
314 
315     ui32ErrorReturn = FAPI_STATUS_SUCCESS;
316 
317     //
318     // Check the arguments.
319     //
320     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
321                                  FlashSectorSizeGet()));
322     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
323 
324     if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT)
325     {
326         //
327         // Find sector number for specified sector.
328         //
329         ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet();
330         ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet();
331 
332         //
333         // Adjust CCFG address to the 32-bit CCFG word holding the
334         // protect-bit for the specified sector.
335         //
336         ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT);
337 
338         //
339         // Find value to program by setting the protect-bit which
340         // corresponds to specified sector number, to 0.
341         // Leave other protect-bits unchanged.
342         //
343         ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) &
344                                    *(uint32_t *)ui32CcfgSectorAddr;
345 
346         ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr,
347                                        CCFG_SIZE_SECT_PROT);
348     }
349 
350     //
351     // Return status.
352     //
353     return(ui32ErrorReturn);
354 }
355 
356 //*****************************************************************************
357 //
358 //! Erase a flash sector
359 //
360 //*****************************************************************************
361 uint32_t
FlashSectorErase(uint32_t ui32SectorAddress)362 FlashSectorErase(uint32_t ui32SectorAddress)
363 {
364     uint32_t ui32ErrorReturn;
365     FlashSectorErasePointer_t FuncPointer;
366 
367     //
368     // Check the arguments.
369     //
370     ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() -
371                                  FlashSectorSizeGet()));
372     ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00);
373 
374     //
375     // Call ROM function
376     //
377     FuncPointer = (uint32_t (*)(uint32_t)) (ROM_API_FLASH_TABLE[5]);
378     ui32ErrorReturn = FuncPointer(ui32SectorAddress);
379 
380     //
381     // Enable standby in flash bank since ROM function migth have disabled it
382     //
383     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
384 
385     //
386     // Return status of operation.
387     //
388     return(ui32ErrorReturn);
389 
390 }
391 
392 
393 //*****************************************************************************
394 //
395 //! Programs unprotected main bank flash sectors
396 //
397 //*****************************************************************************
398 uint32_t
FlashProgram(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)399 FlashProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count)
400 {
401     uint32_t ui32ErrorReturn;
402     FlashPrgPointer_t FuncPointer;
403 
404     //
405     // Check the arguments.
406     //
407     ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashSizeGet()));
408 
409     //
410     // Call ROM function
411     //
412     FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ROM_API_FLASH_TABLE[6]);
413     ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
414 
415     //
416     // Enable standby in flash bank since ROM function migth have disabled it
417     //
418     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
419 
420     //
421     // Return status of operation.
422     //
423     return(ui32ErrorReturn);
424 
425 }
426 
427 //*****************************************************************************
428 //
429 //! Reads efuse data from specified row
430 //
431 //*****************************************************************************
432 bool
FlashEfuseReadRow(uint32_t * pui32EfuseData,uint32_t ui32RowAddress)433 FlashEfuseReadRow(uint32_t *pui32EfuseData, uint32_t ui32RowAddress)
434 {
435     bool bStatus;
436 
437     //
438     // Make sure the clock for the efuse is enabled
439     //
440     HWREG(FLASH_BASE + FLASH_O_CFG) &= ~FLASH_CFG_DIS_EFUSECLK;
441 
442     //
443     // Set timing for EFUSE read operations.
444     //
445     HWREG(FLASH_BASE + FLASH_O_EFUSEREAD) |= ((5 << FLASH_EFUSEREAD_READCLOCK_S) &
446             FLASH_EFUSEREAD_READCLOCK_M);
447 
448     //
449     // Clear status register.
450     //
451     HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) = 0;
452 
453     //
454     // Select the FuseROM block 0.
455     //
456     HWREG(FLASH_BASE + FLASH_O_EFUSEADDR) = 0x00000000;
457 
458     //
459     // Start the read operation.
460     //
461     HWREG(FLASH_BASE + FLASH_O_EFUSE) =
462         (DUMPWORD_INSTR << FLASH_EFUSE_INSTRUCTION_S) |
463         (ui32RowAddress & FLASH_EFUSE_DUMPWORD_M);
464 
465     //
466     // Wait for operation to finish.
467     //
468     while(!(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_DONE))
469     {
470     }
471 
472     //
473     // Check if error reported.
474     //
475     if(HWREG(FLASH_BASE + FLASH_O_EFUSEERROR) & FLASH_EFUSEERROR_CODE_M)
476     {
477         //
478         // Set error status.
479         //
480         bStatus = 1;
481 
482         //
483         // Clear data.
484         //
485         *pui32EfuseData = 0;
486     }
487     else
488     {
489         //
490         // Set ok status.
491         //
492         bStatus = 0;
493 
494         //
495         // No error. Get data from data register.
496         //
497         *pui32EfuseData = HWREG(FLASH_BASE + FLASH_O_DATALOWER);
498     }
499 
500     //
501     // Disable the efuse clock to conserve power
502     //
503     HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_EFUSECLK;
504 
505     //
506     // Return the data.
507     //
508     return(bStatus);
509 }
510 
511 
512 //*****************************************************************************
513 //
514 //! Disables all sectors for erase and programming on the active bank
515 //
516 //*****************************************************************************
517 void
FlashDisableSectorsForWrite(void)518 FlashDisableSectorsForWrite(void)
519 {
520     //
521     // Configure flash back to read mode
522     //
523     SetReadMode();
524 
525     //
526     // Disable Level 1 Protection.
527     //
528     HWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;
529 
530     //
531     // Disable all sectors for erase and programming.
532     //
533     HWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;
534 
535     //
536     // Enable Level 1 Protection.
537     //
538     HWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;
539 
540     //
541     // Protect sectors from sector erase.
542     //
543     HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;
544     HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;
545     HWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;
546     HWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;
547 }
548 
549 //*****************************************************************************
550 //
551 //! \internal
552 //! Used to set flash in read mode.
553 //!
554 //! Flash is configured with values loaded from OTP dependent on the current
555 //! regulator mode.
556 //!
557 //! \return None.
558 //
559 //*****************************************************************************
560 static void
SetReadMode(void)561 SetReadMode(void)
562 {
563     uint32_t ui32TrimValue;
564     uint32_t ui32Value;
565 
566     //
567     // Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,
568     // VIN_AT_X and VIN_BY_PASS for read mode
569     //
570     if(HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_PWRCTL) &
571        AON_SYSCTL_PWRCTL_EXT_REG_MODE)
572     {
573         // Select trim values for external regulator mode:
574         // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)
575         // COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 6:5)
576         // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
577         HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
578 
579         ui32TrimValue =
580            HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
581 
582         ui32Value = ((ui32TrimValue &
583                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>
584                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<
585                     FLASH_CFG_STANDBY_MODE_SEL_S;
586 
587         ui32Value |= ((ui32TrimValue &
588                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>
589                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<
590                      FLASH_CFG_STANDBY_PW_SEL_S;
591 
592         // Configure DIS_STANDBY (OTP offset 0x308 bit 4).
593         // Configure DIS_IDLE    (OTP offset 0x308 bit 3).
594         ui32Value |= ((ui32TrimValue &
595                        (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |
596                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>
597                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<
598                         FLASH_CFG_DIS_IDLE_S;
599 
600         HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
601                                            ~(FLASH_CFG_STANDBY_MODE_SEL_M |
602                                              FLASH_CFG_STANDBY_PW_SEL_M   |
603                                              FLASH_CFG_DIS_STANDBY_M      |
604                                              FLASH_CFG_DIS_IDLE_M)) | ui32Value;
605 
606         // Check if sample and hold functionality is disabled.
607         if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
608         {
609             //
610             // Wait for disabled sample and hold functionality to be stable.
611             //
612             while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
613             {
614             }
615         }
616 
617         // Configure VIN_AT_X (OTP offset 0x308 bits 2:0)
618         ui32Value = ((ui32TrimValue &
619                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>
620                       FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<
621                     FLASH_FSEQPMP_VIN_AT_X_S;
622 
623         // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
624         // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
625         // VIN_BY_PASS should be 1
626         if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
627             FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
628         {
629             ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
630         }
631 
632         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
633         HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
634                                     (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
635                                      ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
636                                        FLASH_FSEQPMP_VIN_AT_X_M))  | ui32Value;
637         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
638     }
639     else
640     {
641         // Select trim values for internal regulator mode:
642         // Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)
643         // COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 14:13)
644         // Must be done while the register bit field CONFIG.DIS_STANDBY = 1
645         HWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;
646 
647         ui32TrimValue =
648            HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);
649 
650         ui32Value = ((ui32TrimValue &
651                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>
652                       FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<
653                     FLASH_CFG_STANDBY_MODE_SEL_S;
654 
655         ui32Value |= ((ui32TrimValue &
656                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>
657                        FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<
658                      FLASH_CFG_STANDBY_PW_SEL_S;
659 
660         // Configure DIS_STANDBY (OTP offset 0x308 bit 12).
661         // Configure DIS_IDLE    (OTP offset 0x308 bit 11).
662         ui32Value |= ((ui32TrimValue &
663                        (FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |
664                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>
665                         FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<
666                         FLASH_CFG_DIS_IDLE_S;
667 
668         HWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &
669                                            ~(FLASH_CFG_STANDBY_MODE_SEL_M |
670                                              FLASH_CFG_STANDBY_PW_SEL_M   |
671                                              FLASH_CFG_DIS_STANDBY_M      |
672                                              FLASH_CFG_DIS_IDLE_M)) | ui32Value;
673 
674         // Check if sample and hold functionality is disabled.
675         if(HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE)
676         {
677             //
678             // Wait for disabled sample and hold functionality to be stable.
679             //
680             while(!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))
681             {
682             }
683         }
684 
685         // Configure VIN_AT_X (OTP offset 0x308 bits 10:8)
686         ui32Value = (((ui32TrimValue &
687                        FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>
688                        FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<
689                        FLASH_FSEQPMP_VIN_AT_X_S);
690 
691         // Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.
692         // If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise
693         // VIN_BY_PASS should be 1
694         if(((ui32Value & FLASH_FSEQPMP_VIN_AT_X_M) >>
695             FLASH_FSEQPMP_VIN_AT_X_S) != 0x7)
696         {
697             ui32Value |= FLASH_FSEQPMP_VIN_BY_PASS;
698         }
699 
700         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;
701         HWREG(FLASH_BASE + FLASH_O_FSEQPMP) =
702                                     (HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &
703                                      ~(FLASH_FSEQPMP_VIN_BY_PASS_M |
704                                        FLASH_FSEQPMP_VIN_AT_X_M)) | ui32Value;
705         HWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;
706     }
707 }
708 
709 //*****************************************************************************
710 //
711 // HAPI Flash program function
712 //
713 //*****************************************************************************
714 uint32_t
MemBusWrkAroundHapiProgramFlash(uint8_t * pui8DataBuffer,uint32_t ui32Address,uint32_t ui32Count)715 MemBusWrkAroundHapiProgramFlash(uint8_t *pui8DataBuffer, uint32_t ui32Address,
716                                 uint32_t ui32Count)
717 {
718     uint32_t ui32ErrorReturn;
719     FlashPrgPointer_t FuncPointer;
720     uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (5 * 4));
721 
722     //
723     // Call ROM function
724     //
725     FuncPointer = (uint32_t (*)(uint8_t *, uint32_t, uint32_t)) (ui32RomAddr);
726     ui32ErrorReturn = FuncPointer( pui8DataBuffer, ui32Address, ui32Count);
727 
728     //
729     // Enable standby in flash bank since ROM function migth have disabled it
730     //
731     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
732 
733     //
734     // Return status of operation.
735     //
736     return(ui32ErrorReturn);
737 }
738 
739 //*****************************************************************************
740 //
741 // HAPI Flash sector erase function
742 //
743 //*****************************************************************************
744 uint32_t
MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)745 MemBusWrkAroundHapiEraseSector(uint32_t ui32Address)
746 {
747     uint32_t ui32ErrorReturn;
748 
749     FlashSectorErasePointer_t FuncPointer;
750     uint32_t ui32RomAddr = HWREG(ROM_HAPI_TABLE_ADDR + (3 * 4));
751 
752     //
753     // Call ROM function
754     //
755     FuncPointer = (uint32_t (*)(uint32_t)) (ui32RomAddr);
756     ui32ErrorReturn = FuncPointer(ui32Address);
757 
758     //
759     // Enable standby in flash bank since ROM function migth have disabled it
760     //
761     HWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN ) = 0;
762 
763     //
764     // Return status of operation.
765     //
766     return(ui32ErrorReturn);
767 }
768