1 //*****************************************************************************
2 //
3 //  am_hal_cachectrl.c
4 //! @file
5 //!
6 //! @brief Functions for interfacing with the CACHE controller.
7 //!
8 //! @addtogroup clkgen2 Clock Generator (CACHE)
9 //! @ingroup apollo2hal
10 //! @{
11 //
12 //*****************************************************************************
13 
14 //*****************************************************************************
15 //
16 // Copyright (c) 2017, Ambiq Micro
17 // All rights reserved.
18 //
19 // Redistribution and use in source and binary forms, with or without
20 // modification, are permitted provided that the following conditions are met:
21 //
22 // 1. Redistributions of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // 3. Neither the name of the copyright holder nor the names of its
30 // contributors may be used to endorse or promote products derived from this
31 // software without specific prior written permission.
32 //
33 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
37 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 // POSSIBILITY OF SUCH DAMAGE.
44 //
45 // This is part of revision 1.2.11 of the AmbiqSuite Development Package.
46 //
47 //*****************************************************************************
48 
49 #include <stdint.h>
50 #include <stdbool.h>
51 #include "am_mcu_apollo.h"
52 
53 //*****************************************************************************
54 //
55 // Default settings for the cache.
56 //
57 //*****************************************************************************
58 const am_hal_cachectrl_config_t am_hal_cachectrl_defaults =
59 {
60     1, // ui32EnableCache
61     0, // ui32LRU
62     0, // ui32EnableNCregions
63     AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512, // ui32Config
64     0, // ui32SerialCacheMode
65     3, // ui32FlashCachingEnables
66     1, // ui32EnableCacheClockGating
67     0, // ui32EnableLightSleep
68     1, // ui32Dly
69     1, // ui32SMDly
70     1, // ui32EnableDataClockGating
71     0, // ui32EnableCacheMonitoring
72 };
73 
74 //*****************************************************************************
75 //
76 //! @brief Enable the cache using the supplied settings
77 //!
78 //! @param psConfig - pointer to a config structure containing cache settings.
79 //!
80 //! This function takes in a structure of cache settings, and uses them to
81 //! enable the cache. This function will take care of the necessary register
82 //! writes both in this module and in the power control module, so a separate
83 //! powerctrl call is not necessary.
84 //!
85 //! For most applications, the default cache settings will be the most
86 //! efficient choice. To use the default cache settings with this function, use
87 //! the address of the global am_hal_cachectrl_defaults structure as the
88 //! psConfig argument.
89 //!
90 //! @return None.
91 //
92 //*****************************************************************************
93 void
am_hal_cachectrl_enable(const am_hal_cachectrl_config_t * psConfig)94 am_hal_cachectrl_enable(const am_hal_cachectrl_config_t *psConfig)
95 {
96     uint32_t ui32ConfigValue;
97     uint32_t ui32Timeout;
98 
99     //
100     // Pull the configuration data from the structure, and prepare to write the
101     // cache configuration register.
102     //
103     // NOTE: ICACHE and DCACHE settings were left out from this step. This is a
104     // workaround for a timing issue with early versions of Apollo2 that caused
105     // the cache to incorrectly mark itself valid during the startup sequence.
106     // The workaround calls for us to start the cache, manually invalidate it,
107     // and then enable ICACHE and DCACHE operation.
108     //
109     ui32ConfigValue = (AM_REG_CACHECTRL_CACHECFG_ENABLE( 1 )                                                |
110                        AM_REG_CACHECTRL_CACHECFG_LRU( psConfig->ui32LRU )                                   |
111                        AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0( (psConfig->ui32EnableNCregions & 0x1) >> 0 )   |
112                        AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1( (psConfig->ui32EnableNCregions & 0x2) >> 1 )   |
113                        psConfig->ui32Config                                                                 |
114                        AM_REG_CACHECTRL_CACHECFG_SERIAL(psConfig->ui32SerialCacheMode)                      |
115                        AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE( psConfig->ui32EnableCacheClockGating )      |
116                        AM_REG_CACHECTRL_CACHECFG_CACHE_LS(psConfig->ui32EnableLightSleep )                  |
117                        AM_REG_CACHECTRL_CACHECFG_DLY( psConfig->ui32Dly )                                   |
118                        AM_REG_CACHECTRL_CACHECFG_SMDLY( psConfig->ui32SMDly )                               |
119                        AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE(psConfig->ui32EnableDataClockGating)          |
120                        AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR(psConfig->ui32EnableCacheMonitoring) );
121 
122     //
123     // Make sure the cache is enabled in the power control block.
124     //
125     am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_CACHE);
126 
127     //
128     // Set the initial cache settings.
129     //
130     AM_REG(CACHECTRL, CACHECFG) = ui32ConfigValue;
131 
132     //
133     // Wait for the cache ready signal.
134     //
135     for (ui32Timeout = 0; ui32Timeout < 50; ui32Timeout++)
136     {
137         if (AM_BFM(CACHECTRL, CACHECTRL, CACHE_READY))
138         {
139             break;
140         }
141     }
142 
143     //
144     // Manually invalidate the cache (workaround for the issue described above.)
145     //
146     AM_BFW(CACHECTRL, CACHECTRL, INVALIDATE, 1);
147 
148     //
149     // Wait for the cache ready signal again.
150     //
151     for (ui32Timeout = 0; ui32Timeout < 50; ui32Timeout++)
152     {
153         if (AM_BFM(CACHECTRL, CACHECTRL, CACHE_READY))
154         {
155             break;
156         }
157     }
158 
159     //
160     // Now that the cache is running, and correctly marked invalid, we can OR in
161     // the ICACHE and DCACHE settings.
162     //
163     ui32ConfigValue |= (AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE( (psConfig->ui32FlashCachingEnables & 0x1) >> 0 )   |
164                         AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE( (psConfig->ui32FlashCachingEnables & 0x2) >> 1 ) );
165 
166     //
167     // Write the final configuration settings to the CACHECTRL register.
168     //
169     AM_REG(CACHECTRL, CACHECFG) = ui32ConfigValue;
170 }
171 
172 //*****************************************************************************
173 //
174 //! @brief Disable the cache.
175 //!
176 //! Call this function to completely shut down cache features.
177 //!
178 //! @return None.
179 //
180 //*****************************************************************************
181 void
am_hal_cachectrl_disable(void)182 am_hal_cachectrl_disable(void)
183 {
184     uint32_t ui32CacheCfg;
185 
186     //
187     // Save the cache settings.
188     //
189     ui32CacheCfg = AM_REG(CACHECTRL, CACHECFG);
190 
191     //
192     // Remove the ICACHE and DCACHE settings.
193     //
194     ui32CacheCfg &= (AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE(0) |
195                      AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE(0));
196 
197     //
198     // Write the resulting value back to the register.
199     //
200     AM_REG(CACHECTRL, CACHECFG) = ui32CacheCfg;
201 
202     //
203     // Read the CACHECTRL register a few times
204     //
205     AM_REG(CACHECTRL, CACHECTRL);
206     AM_REG(CACHECTRL, CACHECTRL);
207     AM_REG(CACHECTRL, CACHECTRL);
208 
209     //
210     // Disable the cache completely.
211     //
212     AM_BFW(CACHECTRL, CACHECFG, ENABLE, 0);
213 
214     //
215     // Power the cache down in the powerctrl block.
216     //
217     am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_CACHE_DIS);
218 }
219 
220 //*****************************************************************************
221 //
222 //! @brief Set a default cache configuration.
223 //!
224 //! This function is used to set a default cache configuration.
225 //
226 //*****************************************************************************
227 void
am_hal_cachectrl_config_default(void)228 am_hal_cachectrl_config_default(void)
229 {
230     //
231     // Set PWRCTRL
232     //
233     am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEMEN_CACHE);
234 
235     //
236     // Write a default configuration to the CACHECFG register.
237     //
238     AM_REG(CACHECTRL, CACHECFG) =                                   \
239         AM_REG_CACHECTRL_CACHECFG_ENABLE( 1 )                   |   \
240         AM_REG_CACHECTRL_CACHECFG_LRU( 0 )                      |   \
241         AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0( 0 )               |   \
242         AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1( 0 )               |   \
243         AM_REG_CACHECTRL_CACHECFG_CONFIG_W2_128B_512E           |   \
244         AM_REG_CACHECTRL_CACHECFG_SERIAL( 0 )                   |   \
245         AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE( 1 )            |   \
246         AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE( 1 )            |   \
247         AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE( 1 )            |   \
248         AM_REG_CACHECTRL_CACHECFG_CACHE_LS( 0 )                 |   \
249         AM_REG_CACHECTRL_CACHECFG_DLY( 1 )                      |   \
250         AM_REG_CACHECTRL_CACHECFG_SMDLY( 1 )                    |   \
251         AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE( 1 )             |   \
252         AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR( 0 );
253 
254     //
255     // Write a default configuration to the FLASHCFG register.
256     //
257     AM_REG(CACHECTRL, FLASHCFG) = AM_REG_CACHECTRL_FLASHCFG_RD_WAIT(1);
258 
259     //
260     // Write a default configuration to the CACHECTRL register.
261     //
262     AM_REG(CACHECTRL, CACHECTRL) =                                  \
263         AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE(1)         |   \
264         AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE(0)        |   \
265         AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE(1)         |   \
266         AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE(0)        |   \
267         AM_REG_CACHECTRL_CACHECTRL_RESET_STAT(0)                |   \
268         AM_REG_CACHECTRL_CACHECTRL_INVALIDATE(0);
269 
270     //
271     // Write a default configuration to the NCR0START and NCR0END registers.
272     //
273     AM_REG(CACHECTRL, NCR0START) =                          \
274         AM_REG_CACHECTRL_NCR0START_ADDR(0);
275     AM_REG(CACHECTRL, NCR0END) =                            \
276         AM_REG_CACHECTRL_NCR0END_ADDR(0);
277 
278     //
279     // Write a default configuration to the NCR1START and NCR1END registers.
280     //
281     AM_REG(CACHECTRL, NCR1START) =                          \
282         AM_REG_CACHECTRL_NCR1START_ADDR(0);
283     AM_REG(CACHECTRL, NCR1END) =                            \
284         AM_REG_CACHECTRL_NCR1END_ADDR(0);
285 
286     //
287     // Write a default configuration to the DMONn and IMONn registers.
288     //
289     AM_REG(CACHECTRL, DMON0) =                                      \
290         AM_REG_CACHECTRL_DMON0_DACCESS_COUNT(0);
291     AM_REG(CACHECTRL, DMON1)  =                                     \
292         AM_REG_CACHECTRL_DMON1_DLOOKUP_COUNT(0);
293     AM_REG(CACHECTRL, DMON2)  =                                     \
294         AM_REG_CACHECTRL_DMON2_DHIT_COUNT(0);
295     AM_REG(CACHECTRL, DMON3)  =                                     \
296         AM_REG_CACHECTRL_DMON3_DLINE_COUNT(0);
297     AM_REG(CACHECTRL, IMON0)  =                                     \
298         AM_REG_CACHECTRL_IMON0_IACCESS_COUNT(0);
299     AM_REG(CACHECTRL, IMON1)  =                                     \
300         AM_REG_CACHECTRL_IMON1_ILOOKUP_COUNT(0);
301     AM_REG(CACHECTRL, IMON2)  =                                     \
302         AM_REG_CACHECTRL_IMON2_IHIT_COUNT(0);
303     AM_REG(CACHECTRL, IMON3)  =                                     \
304         AM_REG_CACHECTRL_IMON3_ILINE_COUNT(0);
305 }
306 
307 //*****************************************************************************
308 //
309 //! @brief Enable the flash cache controller via a configuration structure.
310 //!
311 //! @param psConfig - Pointer to a data structure containing all of the data
312 //      necessary to configure the CACHECFG register.
313 //!
314 //! This function is used to configure all fields of the CACHECFG.
315 //
316 //*****************************************************************************
317 void
am_hal_cachectrl_config(am_hal_cachectrl_config_t * psConfig)318 am_hal_cachectrl_config(am_hal_cachectrl_config_t *psConfig)
319 {
320     uint32_t u32ConfigValue;
321 
322     //
323     // Arrange all of the members of the data structure into a single u32 that
324     //  can be written to the register.
325     //
326     u32ConfigValue =
327         AM_REG_CACHECTRL_CACHECFG_ENABLE( psConfig->ui32EnableCache )       |
328         AM_REG_CACHECTRL_CACHECFG_LRU( psConfig->ui32LRU )                  |
329         AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0(
330             (psConfig->ui32EnableNCregions & 0x1) >> 0 )                    |
331         AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1(
332             (psConfig->ui32EnableNCregions & 0x2) >> 1 )                    |
333         psConfig->ui32Config                                                |
334         AM_REG_CACHECTRL_CACHECFG_SERIAL(psConfig->ui32SerialCacheMode)     |
335         AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE(
336             (psConfig->ui32FlashCachingEnables & 0x1) >> 0 )                |
337         AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE(
338             (psConfig->ui32FlashCachingEnables & 0x2) >> 1 )                |
339         AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE(
340             psConfig->ui32EnableCacheClockGating )                          |
341         AM_REG_CACHECTRL_CACHECFG_CACHE_LS(
342             psConfig->ui32EnableLightSleep )                                |
343         AM_REG_CACHECTRL_CACHECFG_DLY( psConfig->ui32Dly )                  |
344         AM_REG_CACHECTRL_CACHECFG_SMDLY( psConfig->ui32SMDly )              |
345         AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE(
346             psConfig->ui32EnableDataClockGating )                           |
347         AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR(
348             psConfig->ui32EnableCacheMonitoring );
349 
350     //
351     // Write the configuration value to the CACHECFG register.
352     //
353     AM_REG(CACHECTRL, CACHECFG) = u32ConfigValue;
354 }
355 
356 //*****************************************************************************
357 //
358 //! @brief Configure the various flash cache controller enables.
359 //!
360 //! @param u32EnableMask  - Mask of features to be enabled.
361 //! @param u32DisableMask - Mask of features to be disabled.
362 //!
363 //! This function is used to enable or disable the various flash cache
364 //! controller configuration enables which consist of the following:
365 //!     AM_HAL_CACHECTRL_CACHECFG_ENABLE                Flash cache controller
366 //!     AM_HAL_CACHECTRL_CACHECFG_LRU_ENABLE            LRU (disabled = LRR)
367 //!     AM_HAL_CACHECTRL_CACHECFG_NC0_ENABLE            Non-cacheable region 0
368 //!     AM_HAL_CACHECTRL_CACHECFG_NC1_ENABLE            Non-cacheable region 1
369 //!     AM_HAL_CACHECTRL_CACHECFG_SERIAL_ENABLE         Serial cache mode
370 //!     AM_HAL_CACHECTRL_CACHECFG_ICACHE_ENABLE         Instruction caching
371 //!     AM_HAL_CACHECTRL_CACHECFG_DCACHE_ENABLE         Data caching.
372 //!     AM_HAL_CACHECTRL_CACHECFG_CACHE_CLKGATE_ENABLE  Cache clock gating
373 //!     AM_HAL_CACHECTRL_CACHECFG_LS_ENABLE             Light sleep cache RAMs
374 //!     AM_HAL_CACHECTRL_CACHECFG_DATA_CLKGATE_ENABLE   Data clock gating
375 //!     AM_HAL_CACHECTRL_CACHECFG_MONITOR_ENABLE        Cache Monitoring Stats
376 //!
377 //! Note that if both an enable and disable are provided in their respective
378 //! masks, the enable will take precendence.
379 //!
380 //! @return The previous status of the flash cache controller enables.
381 //
382 //*****************************************************************************
383 #define CACHECTRL_VALID_ENABLES                         (   \
384         AM_REG_CACHECTRL_CACHECFG_ENABLE_M              |   \
385         AM_REG_CACHECTRL_CACHECFG_LRU_M                 |   \
386         AM_REG_CACHECTRL_CACHECFG_ENABLE_NC0_M          |   \
387         AM_REG_CACHECTRL_CACHECFG_ENABLE_NC1_M          |   \
388         AM_REG_CACHECTRL_CACHECFG_SERIAL_M              |   \
389         AM_REG_CACHECTRL_CACHECFG_ICACHE_ENABLE_M       |   \
390         AM_REG_CACHECTRL_CACHECFG_DCACHE_ENABLE_M       |   \
391         AM_REG_CACHECTRL_CACHECFG_CACHE_CLKGATE_M       |   \
392         AM_REG_CACHECTRL_CACHECFG_CACHE_LS_M            |   \
393         AM_REG_CACHECTRL_CACHECFG_DATA_CLKGATE_M        |   \
394         AM_REG_CACHECTRL_CACHECFG_ENABLE_MONITOR_M )
395 
396 uint32_t
am_hal_cachectrl_cache_enables(uint32_t u32EnableMask,uint32_t u32DisableMask)397 am_hal_cachectrl_cache_enables(uint32_t u32EnableMask, uint32_t u32DisableMask)
398 {
399     uint32_t ui32RetVal = AM_BFR(CACHECTRL, CACHECFG, ENABLE) &
400                           CACHECTRL_VALID_ENABLES;
401 
402     //
403     // Make sure the enable masks include only valid bits.
404     //
405     u32EnableMask  &= CACHECTRL_VALID_ENABLES;
406     u32DisableMask &= CACHECTRL_VALID_ENABLES;
407 
408     //
409     // First, do the disables.
410     //
411     AM_REG(CACHECTRL, CACHECFG) &= ~u32DisableMask;
412 
413     //
414     // Now set the enables.
415     //
416     AM_REG(CACHECTRL, CACHECFG) |= u32EnableMask;
417 
418     return ui32RetVal;
419 }
420 
421 //*****************************************************************************
422 //
423 //! @brief Select the cache configuration type.
424 //!
425 //! This functions only sets the CACHECFG CONFIG field.
426 //!
427 //! @param ui32CacheConfig - The cache configuration value.
428 //!
429 //! This function can be used to select the type of cache.frequency of the main
430 //! system clock.  The ui32CacheConfig parameter should be set to one of the
431 //! following values:
432 //!
433 //!     AM_HAL_CACHECTRL_CACHECFG_CONFIG_DIRECT_256 : Direct mapped,
434 //!         128-bit linesize, 256 entries (2 SRAMs active).
435 //!     AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_256   : Two-way set associative,
436 //!         128-bit linesize, 256 entries (4 SRAMs active).
437 //!     AM_HAL_CACHECTRL_CACHECFG_CONFIG_2WAY_512   : Two-way set associative,
438 //!         128-bit linesize, 512 entries (8 SRAMs active).
439 //!
440 //! @return None.
441 //
442 //*****************************************************************************
443 void
am_hal_cachectrl_cache_config(uint32_t ui32CacheConfig)444 am_hal_cachectrl_cache_config(uint32_t ui32CacheConfig)
445 {
446     //
447     // Clear the bitfield
448     //
449     AM_REG(CACHECTRL, CACHECFG) &= ~AM_REG_CACHECTRL_CACHECFG_CONFIG_M;
450 
451     //
452     // Write the new value to the bitfield.
453     //
454     AM_REG(CACHECTRL, CACHECFG) |= ui32CacheConfig &
455                                    AM_REG_CACHECTRL_CACHECFG_CONFIG_M;
456 }
457 
458 //*****************************************************************************
459 //
460 //! @brief Invalidate the flash cache.
461 //!
462 //! This function is used to invalidate the flash cache.
463 //!
464 //! @return None.
465 //
466 //*****************************************************************************
467 void
am_hal_cachectrl_invalidate_flash_cache(void)468 am_hal_cachectrl_invalidate_flash_cache(void)
469 {
470     //
471     // Write the bit to invalidate the flash cache.
472     // Note - this bit is not sticky, no need to write it back to 0.
473     //
474     AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_INVALIDATE_GO;
475 }
476 
477 //*****************************************************************************
478 //
479 //! @brief Reset cache statistics.
480 //!
481 //! This function is used to reset cache statistics.
482 //!
483 //! @return None.
484 //
485 //*****************************************************************************
486 void
am_hal_cachectrl_reset_statistics(void)487 am_hal_cachectrl_reset_statistics(void)
488 {
489     //
490     // Write the bit to reset flash statistics.
491     // Note - this bit is not sticky, no need to write it back to 0.
492     //
493     AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_RESET_STAT_CLEAR;
494 }
495 
496 //*****************************************************************************
497 //
498 //! @brief Get flash cache sleep mode status.
499 //!
500 //! This function returns flash cache sleep mode statuses.
501 //!
502 //! @return
503 //!     bit0 indicates that flash0 flash sleep mode is enabled.
504 //!     bit1 indicates that flash1 flash sleep mode is enabled.
505 //
506 //*****************************************************************************
507 uint32_t
am_hal_cachectrl_sleep_mode_status(void)508 am_hal_cachectrl_sleep_mode_status(void)
509 {
510     uint32_t ui32Status, ui32Ret;
511 
512     //
513     // Get the current sleep mode status bits.
514     //
515     ui32Status = AM_REG(CACHECTRL, CACHECTRL);
516     ui32Ret = (ui32Status &                                                 \
517                 AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS_M) >>          \
518                 (AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_STATUS_S - 0);
519     ui32Ret |= (ui32Status &                                                \
520                 AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS_M) >>          \
521                 (AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_STATUS_S - 1);
522 
523     return ui32Ret;
524 }
525 
526 //*****************************************************************************
527 //
528 //! @brief Enable or disable flash cache sleep mode.
529 //!
530 //! This function enables or disables flash cache sleep mode.
531 //! @param ui32EnableMask  - bit0 for flash0, bit1 for flash1.
532 //! @param ui32DisableMask - bit0 for flash0, bit1 for flash1.
533 //!
534 //! Note that if both an enable and disable are provided in their respective
535 //! masks, the enable will take precedence.
536 //!
537 //! @return Previous status.
538 //!     bit0 indicates that flash0 flash sleep mode was previously enabled.
539 //!     bit1 indicates that flash1 flash sleep mode was previously enabled.
540 //
541 //*****************************************************************************
542 uint32_t
am_hal_cachectrl_sleep_mode_enable(uint32_t ui32EnableMask,uint32_t ui32DisableMask)543 am_hal_cachectrl_sleep_mode_enable(uint32_t ui32EnableMask,
544                                    uint32_t ui32DisableMask)
545 {
546     uint32_t ui32Ret = am_hal_cachectrl_sleep_mode_status();
547 
548     if ( ui32DisableMask & 0x1 )
549     {
550         AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_DISABLE_M;
551     }
552 
553     if ( ui32DisableMask & 0x2 )
554     {
555         AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_DISABLE_M;
556     }
557 
558     if ( ui32EnableMask & 0x1 )
559     {
560         AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH0_SLM_ENABLE_M;
561     }
562 
563     if ( ui32EnableMask & 0x2 )
564     {
565         AM_REG(CACHECTRL, CACHECTRL) |= AM_REG_CACHECTRL_CACHECTRL_FLASH1_SLM_ENABLE_M;
566     }
567 
568     return ui32Ret;
569 }
570 
571 //*****************************************************************************
572 //
573 // End Doxygen group.
574 //! @}
575 //
576 //*****************************************************************************
577