added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 144:ef7eb2e8f9f7 12 * list of conditions and the following disclaimer in the documentation and/or
<> 144:ef7eb2e8f9f7 13 * other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 14 *
<> 144:ef7eb2e8f9f7 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 144:ef7eb2e8f9f7 16 * contributors may be used to endorse or promote products derived from this
<> 144:ef7eb2e8f9f7 17 * software without specific prior written permission.
<> 144:ef7eb2e8f9f7 18 *
<> 144:ef7eb2e8f9f7 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30
<> 144:ef7eb2e8f9f7 31 #include "fsl_lmem_cache.h"
<> 144:ef7eb2e8f9f7 32 /*******************************************************************************
<> 144:ef7eb2e8f9f7 33 * Definitions
<> 144:ef7eb2e8f9f7 34 ******************************************************************************/
<> 144:ef7eb2e8f9f7 35
<> 144:ef7eb2e8f9f7 36 #define LMEM_CACHEMODE_WIDTH (2U)
<> 144:ef7eb2e8f9f7 37 #define LMEM_CACHEMODE_MASK_UNIT (0x3U)
<> 144:ef7eb2e8f9f7 38
<> 144:ef7eb2e8f9f7 39 /*******************************************************************************
<> 144:ef7eb2e8f9f7 40 * Code
<> 144:ef7eb2e8f9f7 41 ******************************************************************************/
<> 144:ef7eb2e8f9f7 42
<> 144:ef7eb2e8f9f7 43 void LMEM_EnableCodeCache(LMEM_Type *base, bool enable)
<> 144:ef7eb2e8f9f7 44 {
<> 144:ef7eb2e8f9f7 45 if (enable)
<> 144:ef7eb2e8f9f7 46 {
<> 144:ef7eb2e8f9f7 47 /* First, invalidate the entire cache. */
<> 144:ef7eb2e8f9f7 48 LMEM_CodeCacheInvalidateAll(base);
<> 144:ef7eb2e8f9f7 49
<> 144:ef7eb2e8f9f7 50 /* Now enable the cache. */
<> 144:ef7eb2e8f9f7 51 base->PCCCR |= LMEM_PCCCR_ENCACHE_MASK | LMEM_PCCCR_ENWRBUF_MASK;
<> 144:ef7eb2e8f9f7 52 }
<> 144:ef7eb2e8f9f7 53 else
<> 144:ef7eb2e8f9f7 54 {
<> 144:ef7eb2e8f9f7 55 /* First, push any modified contents. */
<> 144:ef7eb2e8f9f7 56 LMEM_CodeCachePushAll(base);
<> 144:ef7eb2e8f9f7 57
<> 144:ef7eb2e8f9f7 58 /* Now disable the cache. */
<> 144:ef7eb2e8f9f7 59 base->PCCCR &= ~(LMEM_PCCCR_ENCACHE_MASK | LMEM_PCCCR_ENWRBUF_MASK);
<> 144:ef7eb2e8f9f7 60 }
<> 144:ef7eb2e8f9f7 61 }
<> 144:ef7eb2e8f9f7 62
<> 144:ef7eb2e8f9f7 63 void LMEM_CodeCacheInvalidateAll(LMEM_Type *base)
<> 144:ef7eb2e8f9f7 64 {
<> 144:ef7eb2e8f9f7 65 /* Enables the processor code bus to invalidate all lines in both ways.
<> 144:ef7eb2e8f9f7 66 and Initiate the processor code bus code cache command. */
<> 144:ef7eb2e8f9f7 67 base->PCCCR |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_GO_MASK;
<> 144:ef7eb2e8f9f7 68
<> 144:ef7eb2e8f9f7 69 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 70 while (base->PCCCR & LMEM_PCCCR_GO_MASK)
<> 144:ef7eb2e8f9f7 71 {
<> 144:ef7eb2e8f9f7 72 }
<> 144:ef7eb2e8f9f7 73
<> 144:ef7eb2e8f9f7 74 /* As a precaution clear the bits to avoid inadvertently re-running this command. */
<> 144:ef7eb2e8f9f7 75 base->PCCCR &= ~(LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
<> 144:ef7eb2e8f9f7 76 }
<> 144:ef7eb2e8f9f7 77
<> 144:ef7eb2e8f9f7 78 void LMEM_CodeCachePushAll(LMEM_Type *base)
<> 144:ef7eb2e8f9f7 79 {
<> 144:ef7eb2e8f9f7 80 /* Enable the processor code bus to push all modified lines. */
<> 144:ef7eb2e8f9f7 81 base->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_GO_MASK;
<> 144:ef7eb2e8f9f7 82
<> 144:ef7eb2e8f9f7 83 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 84 while (base->PCCCR & LMEM_PCCCR_GO_MASK)
<> 144:ef7eb2e8f9f7 85 {
<> 144:ef7eb2e8f9f7 86 }
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 /* As a precaution clear the bits to avoid inadvertently re-running this command. */
<> 144:ef7eb2e8f9f7 89 base->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK);
<> 144:ef7eb2e8f9f7 90 }
<> 144:ef7eb2e8f9f7 91
<> 144:ef7eb2e8f9f7 92 void LMEM_CodeCacheClearAll(LMEM_Type *base)
<> 144:ef7eb2e8f9f7 93 {
<> 144:ef7eb2e8f9f7 94 /* Push and invalidate all. */
<> 144:ef7eb2e8f9f7 95 base->PCCCR |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK |
<> 144:ef7eb2e8f9f7 96 LMEM_PCCCR_GO_MASK;
<> 144:ef7eb2e8f9f7 97
<> 144:ef7eb2e8f9f7 98 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 99 while (base->PCCCR & LMEM_PCCCR_GO_MASK)
<> 144:ef7eb2e8f9f7 100 {
<> 144:ef7eb2e8f9f7 101 }
<> 144:ef7eb2e8f9f7 102
<> 144:ef7eb2e8f9f7 103 /* As a precaution clear the bits to avoid inadvertently re-running this command. */
<> 144:ef7eb2e8f9f7 104 base->PCCCR &= ~(LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK);
<> 144:ef7eb2e8f9f7 105 }
<> 144:ef7eb2e8f9f7 106
<> 144:ef7eb2e8f9f7 107 /*FUNCTION**********************************************************************
<> 144:ef7eb2e8f9f7 108 *
<> 144:ef7eb2e8f9f7 109 * Function Name : LMEM_CodeCacheInvalidateLine
<> 144:ef7eb2e8f9f7 110 * Description : This function invalidates a specific line in the Processor Code bus cache.
<> 144:ef7eb2e8f9f7 111 *
<> 144:ef7eb2e8f9f7 112 * This function invalidates a specific line in the cache. The function invalidates a
<> 144:ef7eb2e8f9f7 113 * line in cache based on the physical address passed in by the user.
<> 144:ef7eb2e8f9f7 114 * Invalidate - Unconditionally clear valid and modify bits of a cache entry
<> 144:ef7eb2e8f9f7 115 *
<> 144:ef7eb2e8f9f7 116 *END**************************************************************************/
<> 144:ef7eb2e8f9f7 117 void LMEM_CodeCacheInvalidateLine(LMEM_Type *base, uint32_t address)
<> 144:ef7eb2e8f9f7 118 {
<> 144:ef7eb2e8f9f7 119 uint32_t pccReg = 0;
<> 144:ef7eb2e8f9f7 120
<> 144:ef7eb2e8f9f7 121 /* Set the invalidate by line command and use the physical address. */
<> 144:ef7eb2e8f9f7 122 pccReg =
<> 144:ef7eb2e8f9f7 123 (base->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(kLMEM_CacheLineInvalidate) | LMEM_PCCLCR_LADSEL_MASK;
<> 144:ef7eb2e8f9f7 124 base->PCCLCR = pccReg;
<> 144:ef7eb2e8f9f7 125
<> 144:ef7eb2e8f9f7 126 /* Set the address and initiate the command. */
<> 144:ef7eb2e8f9f7 127 base->PCCSAR = (address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 130 while (base->PCCSAR & LMEM_PCCSAR_LGO_MASK)
<> 144:ef7eb2e8f9f7 131 {
<> 144:ef7eb2e8f9f7 132 }
<> 144:ef7eb2e8f9f7 133
<> 144:ef7eb2e8f9f7 134 /* No need to clear this command since future line commands will overwrite
<> 144:ef7eb2e8f9f7 135 the line command field. */
<> 144:ef7eb2e8f9f7 136 }
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 void LMEM_CodeCacheInvalidateMultiLines(LMEM_Type *base, uint32_t address, uint32_t length)
<> 144:ef7eb2e8f9f7 139 {
<> 144:ef7eb2e8f9f7 140 uint32_t endAddr = address + length;
<> 144:ef7eb2e8f9f7 141 /* Align address to cache line size. */
<> 144:ef7eb2e8f9f7 142 address = address & ~(LMEM_CACHE_LINE_SIZE - 1U);
<> 144:ef7eb2e8f9f7 143 /* If the length exceeds 4KB, invalidate all. */
<> 144:ef7eb2e8f9f7 144 if (length >= LMEM_CACHE_SIZE_ONEWAY)
<> 144:ef7eb2e8f9f7 145 {
<> 144:ef7eb2e8f9f7 146 LMEM_CodeCacheInvalidateAll(base);
<> 144:ef7eb2e8f9f7 147 }
<> 144:ef7eb2e8f9f7 148 else
<> 144:ef7eb2e8f9f7 149 { /* Proceed with multi-line invalidate. */
<> 144:ef7eb2e8f9f7 150 while (address < endAddr)
<> 144:ef7eb2e8f9f7 151 {
<> 144:ef7eb2e8f9f7 152 LMEM_CodeCacheInvalidateLine(base, address);
<> 144:ef7eb2e8f9f7 153 address = address + LMEM_CACHE_LINE_SIZE;
<> 144:ef7eb2e8f9f7 154 }
<> 144:ef7eb2e8f9f7 155 }
<> 144:ef7eb2e8f9f7 156 }
<> 144:ef7eb2e8f9f7 157
<> 144:ef7eb2e8f9f7 158 void LMEM_CodeCachePushLine(LMEM_Type *base, uint32_t address)
<> 144:ef7eb2e8f9f7 159 {
<> 144:ef7eb2e8f9f7 160 uint32_t pccReg = 0;
<> 144:ef7eb2e8f9f7 161
<> 144:ef7eb2e8f9f7 162 /* Set the push by line command. */
<> 144:ef7eb2e8f9f7 163 pccReg = (base->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(kLMEM_CacheLinePush) | LMEM_PCCLCR_LADSEL_MASK;
<> 144:ef7eb2e8f9f7 164 base->PCCLCR = pccReg;
<> 144:ef7eb2e8f9f7 165
<> 144:ef7eb2e8f9f7 166 /* Set the address and initiate the command. */
<> 144:ef7eb2e8f9f7 167 base->PCCSAR = (address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
<> 144:ef7eb2e8f9f7 168
<> 144:ef7eb2e8f9f7 169 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 170 while (base->PCCSAR & LMEM_PCCSAR_LGO_MASK)
<> 144:ef7eb2e8f9f7 171 {
<> 144:ef7eb2e8f9f7 172 }
<> 144:ef7eb2e8f9f7 173
<> 144:ef7eb2e8f9f7 174 /* No need to clear this command since future line commands will overwrite
<> 144:ef7eb2e8f9f7 175 the line command field. */
<> 144:ef7eb2e8f9f7 176 }
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178 void LMEM_CodeCachePushMultiLines(LMEM_Type *base, uint32_t address, uint32_t length)
<> 144:ef7eb2e8f9f7 179 {
<> 144:ef7eb2e8f9f7 180 uint32_t endAddr = address + length;
<> 144:ef7eb2e8f9f7 181 /* Align address to cache line size. */
<> 144:ef7eb2e8f9f7 182 address = address & ~(LMEM_CACHE_LINE_SIZE - 1U);
<> 144:ef7eb2e8f9f7 183
<> 144:ef7eb2e8f9f7 184 /* If the length exceeds 4KB, push all. */
<> 144:ef7eb2e8f9f7 185 if (length >= LMEM_CACHE_SIZE_ONEWAY)
<> 144:ef7eb2e8f9f7 186 {
<> 144:ef7eb2e8f9f7 187 LMEM_CodeCachePushAll(base);
<> 144:ef7eb2e8f9f7 188 }
<> 144:ef7eb2e8f9f7 189 else
<> 144:ef7eb2e8f9f7 190 { /* Proceed with multi-line push. */
<> 144:ef7eb2e8f9f7 191 while (address < endAddr)
<> 144:ef7eb2e8f9f7 192 {
<> 144:ef7eb2e8f9f7 193 LMEM_CodeCachePushLine(base, address);
<> 144:ef7eb2e8f9f7 194 address = address + LMEM_CACHE_LINE_SIZE;
<> 144:ef7eb2e8f9f7 195 }
<> 144:ef7eb2e8f9f7 196 }
<> 144:ef7eb2e8f9f7 197 }
<> 144:ef7eb2e8f9f7 198
<> 144:ef7eb2e8f9f7 199 void LMEM_CodeCacheClearLine(LMEM_Type *base, uint32_t address)
<> 144:ef7eb2e8f9f7 200 {
<> 144:ef7eb2e8f9f7 201 uint32_t pccReg = 0;
<> 144:ef7eb2e8f9f7 202
<> 144:ef7eb2e8f9f7 203 /* Set the push by line command. */
<> 144:ef7eb2e8f9f7 204 pccReg = (base->PCCLCR & ~LMEM_PCCLCR_LCMD_MASK) | LMEM_PCCLCR_LCMD(kLMEM_CacheLineClear) | LMEM_PCCLCR_LADSEL_MASK;
<> 144:ef7eb2e8f9f7 205 base->PCCLCR = pccReg;
<> 144:ef7eb2e8f9f7 206
<> 144:ef7eb2e8f9f7 207 /* Set the address and initiate the command. */
<> 144:ef7eb2e8f9f7 208 base->PCCSAR = (address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
<> 144:ef7eb2e8f9f7 209
<> 144:ef7eb2e8f9f7 210 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 211 while (base->PCCSAR & LMEM_PCCSAR_LGO_MASK)
<> 144:ef7eb2e8f9f7 212 {
<> 144:ef7eb2e8f9f7 213 }
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 /* No need to clear this command since future line commands will overwrite
<> 144:ef7eb2e8f9f7 216 the line command field. */
<> 144:ef7eb2e8f9f7 217 }
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 void LMEM_CodeCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length)
<> 144:ef7eb2e8f9f7 220 {
<> 144:ef7eb2e8f9f7 221 uint32_t endAddr = address + length;
<> 144:ef7eb2e8f9f7 222 /* Align address to cache line size. */
<> 144:ef7eb2e8f9f7 223 address = address & ~(LMEM_CACHE_LINE_SIZE - 1U);
<> 144:ef7eb2e8f9f7 224
<> 144:ef7eb2e8f9f7 225 /* If the length exceeds 4KB, clear all. */
<> 144:ef7eb2e8f9f7 226 if (length >= LMEM_CACHE_SIZE_ONEWAY)
<> 144:ef7eb2e8f9f7 227 {
<> 144:ef7eb2e8f9f7 228 LMEM_CodeCacheClearAll(base);
<> 144:ef7eb2e8f9f7 229 }
<> 144:ef7eb2e8f9f7 230 else /* Proceed with multi-line clear. */
<> 144:ef7eb2e8f9f7 231 {
<> 144:ef7eb2e8f9f7 232 while (address < endAddr)
<> 144:ef7eb2e8f9f7 233 {
<> 144:ef7eb2e8f9f7 234 LMEM_CodeCacheClearLine(base, address);
<> 144:ef7eb2e8f9f7 235 address = address + LMEM_CACHE_LINE_SIZE;
<> 144:ef7eb2e8f9f7 236 }
<> 144:ef7eb2e8f9f7 237 }
<> 144:ef7eb2e8f9f7 238 }
<> 144:ef7eb2e8f9f7 239
<> 144:ef7eb2e8f9f7 240 status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode)
<> 144:ef7eb2e8f9f7 241 {
<> 144:ef7eb2e8f9f7 242 uint32_t mode = base->PCCRMR;
<> 144:ef7eb2e8f9f7 243 uint32_t shift = LMEM_CACHEMODE_WIDTH * (uint32_t)region; /* Region shift. */
<> 144:ef7eb2e8f9f7 244 uint32_t mask = LMEM_CACHEMODE_MASK_UNIT << shift; /* Region mask. */
<> 144:ef7eb2e8f9f7 245
<> 144:ef7eb2e8f9f7 246 /* If the current cache mode is higher than the requested mode, return error. */
<> 144:ef7eb2e8f9f7 247 if ((uint32_t)cacheMode >= ((mode & mask) >> shift))
<> 144:ef7eb2e8f9f7 248 {
<> 144:ef7eb2e8f9f7 249 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 250 }
<> 144:ef7eb2e8f9f7 251 else
<> 144:ef7eb2e8f9f7 252 { /* Proceed to demote the region. */
<> 144:ef7eb2e8f9f7 253 LMEM_CodeCacheClearAll(base);
<> 144:ef7eb2e8f9f7 254 base->PCCRMR = (mode & ~mask) | cacheMode << shift;
<> 144:ef7eb2e8f9f7 255 return kStatus_Success;
<> 144:ef7eb2e8f9f7 256 }
<> 144:ef7eb2e8f9f7 257 }
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 #if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE
<> 144:ef7eb2e8f9f7 260 void LMEM_EnableSystemCache(LMEM_Type *base, bool enable)
<> 144:ef7eb2e8f9f7 261 {
<> 144:ef7eb2e8f9f7 262 if (enable)
<> 144:ef7eb2e8f9f7 263 {
<> 144:ef7eb2e8f9f7 264 /* First, invalidate the entire cache. */
<> 144:ef7eb2e8f9f7 265 LMEM_SystemCacheInvalidateAll(base);
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 /* Now enable the cache. */
<> 144:ef7eb2e8f9f7 268 base->PSCCR |= LMEM_PSCCR_ENCACHE_MASK | LMEM_PSCCR_ENWRBUF_MASK;
<> 144:ef7eb2e8f9f7 269 }
<> 144:ef7eb2e8f9f7 270 else
<> 144:ef7eb2e8f9f7 271 {
<> 144:ef7eb2e8f9f7 272 /* First, push any modified contents. */
<> 144:ef7eb2e8f9f7 273 LMEM_SystemCachePushAll(base);
<> 144:ef7eb2e8f9f7 274
<> 144:ef7eb2e8f9f7 275 /* Now disable the cache. */
<> 144:ef7eb2e8f9f7 276 base->PSCCR &= ~(LMEM_PSCCR_ENCACHE_MASK | LMEM_PSCCR_ENWRBUF_MASK);
<> 144:ef7eb2e8f9f7 277 }
<> 144:ef7eb2e8f9f7 278 }
<> 144:ef7eb2e8f9f7 279
<> 144:ef7eb2e8f9f7 280 void LMEM_SystemCacheInvalidateAll(LMEM_Type *base)
<> 144:ef7eb2e8f9f7 281 {
<> 144:ef7eb2e8f9f7 282 /* Enables the processor system bus to invalidate all lines in both ways.
<> 144:ef7eb2e8f9f7 283 and Initiate the processor system bus cache command. */
<> 144:ef7eb2e8f9f7 284 base->PSCCR |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_GO_MASK;
<> 144:ef7eb2e8f9f7 285
<> 144:ef7eb2e8f9f7 286 /* Wait until the cache command completes */
<> 144:ef7eb2e8f9f7 287 while (base->PSCCR & LMEM_PSCCR_GO_MASK)
<> 144:ef7eb2e8f9f7 288 {
<> 144:ef7eb2e8f9f7 289 }
<> 144:ef7eb2e8f9f7 290
<> 144:ef7eb2e8f9f7 291 /* As a precaution clear the bits to avoid inadvertently re-running this command. */
<> 144:ef7eb2e8f9f7 292 base->PSCCR &= ~(LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
<> 144:ef7eb2e8f9f7 293 }
<> 144:ef7eb2e8f9f7 294
<> 144:ef7eb2e8f9f7 295 void LMEM_SystemCachePushAll(LMEM_Type *base)
<> 144:ef7eb2e8f9f7 296 {
<> 144:ef7eb2e8f9f7 297 /* Enable the processor system bus to push all modified lines. */
<> 144:ef7eb2e8f9f7 298 base->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_GO_MASK;
<> 144:ef7eb2e8f9f7 299
<> 144:ef7eb2e8f9f7 300 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 301 while (base->PSCCR & LMEM_PSCCR_GO_MASK)
<> 144:ef7eb2e8f9f7 302 {
<> 144:ef7eb2e8f9f7 303 }
<> 144:ef7eb2e8f9f7 304
<> 144:ef7eb2e8f9f7 305 /* As a precaution clear the bits to avoid inadvertently re-running this command. */
<> 144:ef7eb2e8f9f7 306 base->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK);
<> 144:ef7eb2e8f9f7 307 }
<> 144:ef7eb2e8f9f7 308
<> 144:ef7eb2e8f9f7 309 void LMEM_SystemCacheClearAll(LMEM_Type *base)
<> 144:ef7eb2e8f9f7 310 {
<> 144:ef7eb2e8f9f7 311 /* Push and invalidate all. */
<> 144:ef7eb2e8f9f7 312 base->PSCCR |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK |
<> 144:ef7eb2e8f9f7 313 LMEM_PSCCR_GO_MASK;
<> 144:ef7eb2e8f9f7 314
<> 144:ef7eb2e8f9f7 315 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 316 while (base->PSCCR & LMEM_PSCCR_GO_MASK)
<> 144:ef7eb2e8f9f7 317 {
<> 144:ef7eb2e8f9f7 318 }
<> 144:ef7eb2e8f9f7 319
<> 144:ef7eb2e8f9f7 320 /* As a precaution clear the bits to avoid inadvertently re-running this command. */
<> 144:ef7eb2e8f9f7 321 base->PSCCR &= ~(LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK | LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK);
<> 144:ef7eb2e8f9f7 322 }
<> 144:ef7eb2e8f9f7 323
<> 144:ef7eb2e8f9f7 324 void LMEM_SystemCacheInvalidateLine(LMEM_Type *base, uint32_t address)
<> 144:ef7eb2e8f9f7 325 {
<> 144:ef7eb2e8f9f7 326 uint32_t pscReg = 0;
<> 144:ef7eb2e8f9f7 327
<> 144:ef7eb2e8f9f7 328 /* Set the invalidate by line command and use the physical address. */
<> 144:ef7eb2e8f9f7 329 pscReg =
<> 144:ef7eb2e8f9f7 330 (base->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(kLMEM_CacheLineInvalidate) | LMEM_PSCLCR_LADSEL_MASK;
<> 144:ef7eb2e8f9f7 331 base->PSCLCR = pscReg;
<> 144:ef7eb2e8f9f7 332
<> 144:ef7eb2e8f9f7 333 /* Set the address and initiate the command. */
<> 144:ef7eb2e8f9f7 334 base->PSCSAR = (address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
<> 144:ef7eb2e8f9f7 335
<> 144:ef7eb2e8f9f7 336 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 337 while (base->PSCSAR & LMEM_PSCSAR_LGO_MASK)
<> 144:ef7eb2e8f9f7 338 {
<> 144:ef7eb2e8f9f7 339 }
<> 144:ef7eb2e8f9f7 340
<> 144:ef7eb2e8f9f7 341 /* No need to clear this command since future line commands will overwrite
<> 144:ef7eb2e8f9f7 342 the line command field. */
<> 144:ef7eb2e8f9f7 343 }
<> 144:ef7eb2e8f9f7 344
<> 144:ef7eb2e8f9f7 345 void LMEM_SystemCacheInvalidateMultiLines(LMEM_Type *base, uint32_t address, uint32_t length)
<> 144:ef7eb2e8f9f7 346 {
<> 144:ef7eb2e8f9f7 347 uint32_t endAddr = address + length;
<> 144:ef7eb2e8f9f7 348 address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size */
<> 144:ef7eb2e8f9f7 349
<> 144:ef7eb2e8f9f7 350 /* If the length exceeds 4KB, invalidate all. */
<> 144:ef7eb2e8f9f7 351 if (length >= LMEM_CACHE_SIZE_ONEWAY)
<> 144:ef7eb2e8f9f7 352 {
<> 144:ef7eb2e8f9f7 353 LMEM_SystemCacheInvalidateAll(base);
<> 144:ef7eb2e8f9f7 354 }
<> 144:ef7eb2e8f9f7 355 else /* Proceed with multi-line invalidate. */
<> 144:ef7eb2e8f9f7 356 {
<> 144:ef7eb2e8f9f7 357 while (address < endAddr)
<> 144:ef7eb2e8f9f7 358 {
<> 144:ef7eb2e8f9f7 359 LMEM_SystemCacheInvalidateLine(base, address);
<> 144:ef7eb2e8f9f7 360 address = address + LMEM_CACHE_LINE_SIZE;
<> 144:ef7eb2e8f9f7 361 }
<> 144:ef7eb2e8f9f7 362 }
<> 144:ef7eb2e8f9f7 363 }
<> 144:ef7eb2e8f9f7 364
<> 144:ef7eb2e8f9f7 365 void LMEM_SystemCachePushLine(LMEM_Type *base, uint32_t address)
<> 144:ef7eb2e8f9f7 366 {
<> 144:ef7eb2e8f9f7 367 uint32_t pscReg = 0;
<> 144:ef7eb2e8f9f7 368
<> 144:ef7eb2e8f9f7 369 /* Set the push by line command. */
<> 144:ef7eb2e8f9f7 370 pscReg = (base->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(kLMEM_CacheLinePush) | LMEM_PSCLCR_LADSEL_MASK;
<> 144:ef7eb2e8f9f7 371 base->PSCLCR = pscReg;
<> 144:ef7eb2e8f9f7 372
<> 144:ef7eb2e8f9f7 373 /* Set the address and initiate the command. */
<> 144:ef7eb2e8f9f7 374 base->PSCSAR = (address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
<> 144:ef7eb2e8f9f7 375
<> 144:ef7eb2e8f9f7 376 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 377 while (base->PSCSAR & LMEM_PSCSAR_LGO_MASK)
<> 144:ef7eb2e8f9f7 378 {
<> 144:ef7eb2e8f9f7 379 }
<> 144:ef7eb2e8f9f7 380
<> 144:ef7eb2e8f9f7 381 /* No need to clear this command since future line commands will overwrite
<> 144:ef7eb2e8f9f7 382 the line command field. */
<> 144:ef7eb2e8f9f7 383 }
<> 144:ef7eb2e8f9f7 384
<> 144:ef7eb2e8f9f7 385 void LMEM_SystemCachePushMultiLines(LMEM_Type *base, uint32_t address, uint32_t length)
<> 144:ef7eb2e8f9f7 386 {
<> 144:ef7eb2e8f9f7 387 uint32_t endAddr = address + length;
<> 144:ef7eb2e8f9f7 388 address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size. */
<> 144:ef7eb2e8f9f7 389
<> 144:ef7eb2e8f9f7 390 /* If the length exceeds 4KB, push all. */
<> 144:ef7eb2e8f9f7 391 if (length >= LMEM_CACHE_SIZE_ONEWAY)
<> 144:ef7eb2e8f9f7 392 {
<> 144:ef7eb2e8f9f7 393 LMEM_SystemCachePushAll(base);
<> 144:ef7eb2e8f9f7 394 }
<> 144:ef7eb2e8f9f7 395 else
<> 144:ef7eb2e8f9f7 396 { /* Proceed with multi-line push. */
<> 144:ef7eb2e8f9f7 397 while (address < endAddr)
<> 144:ef7eb2e8f9f7 398 {
<> 144:ef7eb2e8f9f7 399 LMEM_SystemCachePushLine(base, address);
<> 144:ef7eb2e8f9f7 400 address = address + LMEM_CACHE_LINE_SIZE;
<> 144:ef7eb2e8f9f7 401 }
<> 144:ef7eb2e8f9f7 402 }
<> 144:ef7eb2e8f9f7 403 }
<> 144:ef7eb2e8f9f7 404
<> 144:ef7eb2e8f9f7 405 void LMEM_SystemCacheClearLine(LMEM_Type *base, uint32_t address)
<> 144:ef7eb2e8f9f7 406 {
<> 144:ef7eb2e8f9f7 407 uint32_t pscReg = 0;
<> 144:ef7eb2e8f9f7 408
<> 144:ef7eb2e8f9f7 409 /* Set the push by line command. */
<> 144:ef7eb2e8f9f7 410 pscReg = (base->PSCLCR & ~LMEM_PSCLCR_LCMD_MASK) | LMEM_PSCLCR_LCMD(kLMEM_CacheLineClear) | LMEM_PSCLCR_LADSEL_MASK;
<> 144:ef7eb2e8f9f7 411 base->PSCLCR = pscReg;
<> 144:ef7eb2e8f9f7 412
<> 144:ef7eb2e8f9f7 413 /* Set the address and initiate the command. */
<> 144:ef7eb2e8f9f7 414 base->PSCSAR = (address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
<> 144:ef7eb2e8f9f7 415
<> 144:ef7eb2e8f9f7 416 /* Wait until the cache command completes. */
<> 144:ef7eb2e8f9f7 417 while (base->PSCSAR & LMEM_PSCSAR_LGO_MASK)
<> 144:ef7eb2e8f9f7 418 {
<> 144:ef7eb2e8f9f7 419 }
<> 144:ef7eb2e8f9f7 420
<> 144:ef7eb2e8f9f7 421 /* No need to clear this command since future line commands will overwrite
<> 144:ef7eb2e8f9f7 422 the line command field. */
<> 144:ef7eb2e8f9f7 423 }
<> 144:ef7eb2e8f9f7 424
<> 144:ef7eb2e8f9f7 425 void LMEM_SystemCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length)
<> 144:ef7eb2e8f9f7 426 {
<> 144:ef7eb2e8f9f7 427 uint32_t endAddr = address + length;
<> 144:ef7eb2e8f9f7 428 address = address & ~(LMEM_CACHE_LINE_SIZE - 1U); /* Align address to cache line size. */
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 /* If the length exceeds 4KB, clear all. */
<> 144:ef7eb2e8f9f7 431 if (length >= LMEM_CACHE_SIZE_ONEWAY)
<> 144:ef7eb2e8f9f7 432 {
<> 144:ef7eb2e8f9f7 433 LMEM_SystemCacheClearAll(base);
<> 144:ef7eb2e8f9f7 434 }
<> 144:ef7eb2e8f9f7 435 else /* Proceed with multi-line clear. */
<> 144:ef7eb2e8f9f7 436 {
<> 144:ef7eb2e8f9f7 437 while (address < endAddr)
<> 144:ef7eb2e8f9f7 438 {
<> 144:ef7eb2e8f9f7 439 LMEM_SystemCacheClearLine(base, address);
<> 144:ef7eb2e8f9f7 440 address = address + LMEM_CACHE_LINE_SIZE;
<> 144:ef7eb2e8f9f7 441 }
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443 }
<> 144:ef7eb2e8f9f7 444
<> 144:ef7eb2e8f9f7 445 status_t LMEM_SystemCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode)
<> 144:ef7eb2e8f9f7 446 {
<> 144:ef7eb2e8f9f7 447 uint32_t mode = base->PSCRMR;
<> 144:ef7eb2e8f9f7 448 uint32_t shift = LMEM_CACHEMODE_WIDTH * (uint32_t)region; /* Region shift. */
<> 144:ef7eb2e8f9f7 449 uint32_t mask = LMEM_CACHEMODE_MASK_UNIT << shift; /* Region mask. */
<> 144:ef7eb2e8f9f7 450
<> 144:ef7eb2e8f9f7 451 /* If the current cache mode is higher than the requested mode, return error. */
<> 144:ef7eb2e8f9f7 452 if ((uint32_t)cacheMode >= ((mode & mask) >> shift))
<> 144:ef7eb2e8f9f7 453 {
<> 144:ef7eb2e8f9f7 454 return kStatus_Fail;
<> 144:ef7eb2e8f9f7 455 }
<> 144:ef7eb2e8f9f7 456 else
<> 144:ef7eb2e8f9f7 457 { /* Proceed to demote the region. */
<> 144:ef7eb2e8f9f7 458 LMEM_SystemCacheClearAll(base);
<> 144:ef7eb2e8f9f7 459 base->PSCRMR = (mode & ~mask) | (cacheMode << shift);
<> 144:ef7eb2e8f9f7 460 return kStatus_Success;
<> 144:ef7eb2e8f9f7 461 }
<> 144:ef7eb2e8f9f7 462 }
<> 144:ef7eb2e8f9f7 463 #endif /* FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE */