![]() |
|
|||
File indexing completed on 2025-05-11 08:23:39
0001 /* SPDX-License-Identifier: BSD-3-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSBSPsARMTMS570 0007 * 0008 * @brief This source file contains errata SSWF021#45 workaround 0009 * implementation. 0010 */ 0011 0012 /* 0013 * Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 0014 * 0015 * 0016 * Redistribution and use in source and binary forms, with or without 0017 * modification, are permitted provided that the following conditions 0018 * are met: 0019 * 0020 * Redistributions of source code must retain the above copyright 0021 * notice, this list of conditions and the following disclaimer. 0022 * 0023 * Redistributions in binary form must reproduce the above copyright 0024 * notice, this list of conditions and the following disclaimer in the 0025 * documentation and/or other materials provided with the 0026 * distribution. 0027 * 0028 * Neither the name of Texas Instruments Incorporated nor the names of 0029 * its contributors may be used to endorse or promote products derived 0030 * from this software without specific prior written permission. 0031 * 0032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0033 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0034 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0035 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0036 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0037 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0038 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0039 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0040 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0041 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0042 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0043 * 0044 */ 0045 #include <bsp/ti_herc/errata_SSWF021_45.h> 0046 #include <bsp/tms570.h> 0047 0048 #define SYS_CLKSRC_PLL1 0x00000002U 0049 #define SYS_CLKSRC_PLL2 0x00000040U 0050 #define SYS_CLKCNTRL_PENA 0x00000100U 0051 #define ESM_SR1_PLL1SLIP 0x400U 0052 #define ESM_SR4_PLL2SLIP 0x400U 0053 #define PLL1 0x08 0054 #define PLL2 0x80 0055 #define dcc1CNT1_CLKSRC_PLL1 0x0000A000U 0056 #define dcc1CNT1_CLKSRC_PLL2 0x0000A001U 0057 0058 static uint32_t check_frequency(uint32_t cnt1_clksrc); 0059 static uint32_t disable_plls(uint32_t plls); 0060 0061 /** @fn uint32_t _errata_SSWF021_45_both_plls(uint32_t count) 0062 * @brief This handles the errata for PLL1 and PLL2. This function is called 0063 * in device startup 0064 * 0065 * @param[in] count : Number of retries until both PLLs are locked 0066 * successfully Minimum value recommended is 5 0067 * 0068 * @return 0 = Success (the PLL or both PLLs have successfully locked and then 0069 * been disabled) 0070 * 1 = PLL1 failed to successfully lock in "count" tries 0071 * 2 = PLL2 failed to successfully lock in "count" tries 0072 * 3 = Neither PLL1 nor PLL2 successfully locked in "count" tries 0073 * 4 = The workaround function was not able to disable at least one of 0074 * the PLLs. The most likely reason is that a PLL is already being 0075 * used as a clock source. This can be caused by the workaround 0076 * function being called from the wrong place in the code. 0077 */ 0078 uint32_t _errata_SSWF021_45_both_plls(uint32_t count) { 0079 uint32_t failCode, retries, clkCntlSav; 0080 0081 /* save CLKCNTL */ 0082 clkCntlSav = TMS570_SYS1.CLKCNTL; 0083 /* First set VCLK2 = HCLK */ 0084 TMS570_SYS1.CLKCNTL = clkCntlSav & 0x000F0100U; 0085 /* Now set VCLK = HCLK and enable peripherals */ 0086 TMS570_SYS1.CLKCNTL = SYS_CLKCNTRL_PENA; 0087 failCode = 0U; 0088 for (retries = 0U; (retries < count); retries++) { 0089 failCode = 0U; 0090 /* Disable PLL1 and PLL2 */ 0091 failCode = disable_plls(SYS_CLKSRC_PLL1 | SYS_CLKSRC_PLL2); 0092 if (failCode != 0U) { 0093 break; 0094 } 0095 0096 /* Clear Global Status Register */ 0097 TMS570_SYS1.GLBSTAT = 0x00000301U; 0098 /* Clear the ESM PLL slip flags */ 0099 TMS570_ESM.SR[0U] = ESM_SR1_PLL1SLIP; 0100 TMS570_ESM.SR4 = ESM_SR4_PLL2SLIP; 0101 /* set both PLLs to OSCIN/1*27/(2*1) */ 0102 TMS570_SYS1.PLLCTL1 = 0x20001A00U; 0103 TMS570_SYS1.PLLCTL2 = 0x3FC0723DU; 0104 TMS570_SYS2.PLLCTL3 = 0x20001A00U; 0105 TMS570_SYS1.CSDISCLR = SYS_CLKSRC_PLL1 | SYS_CLKSRC_PLL2; 0106 /* Check for (PLL1 valid or PLL1 slip) and (PLL2 valid or PLL2 slip) */ 0107 while ((((TMS570_SYS1.CSVSTAT & SYS_CLKSRC_PLL1) == 0U) && 0108 ((TMS570_ESM.SR[0U] & ESM_SR1_PLL1SLIP) == 0U)) || 0109 (((TMS570_SYS1.CSVSTAT & SYS_CLKSRC_PLL2) == 0U) && 0110 ((TMS570_ESM.SR4 & ESM_SR4_PLL2SLIP) == 0U))) { 0111 /* Wait */ 0112 } 0113 /* If PLL1 valid, check the frequency */ 0114 if (((TMS570_ESM.SR[0U] & ESM_SR1_PLL1SLIP) != 0U) || 0115 ((TMS570_SYS1.GLBSTAT & 0x00000300U) != 0U)) { 0116 failCode |= 1U; 0117 } else { 0118 failCode |= check_frequency(dcc1CNT1_CLKSRC_PLL1); 0119 } 0120 /* If PLL2 valid, check the frequency */ 0121 if (((TMS570_ESM.SR4 & ESM_SR4_PLL2SLIP) != 0U) || 0122 ((TMS570_SYS1.GLBSTAT & 0x00000300U) != 0U)) { 0123 failCode |= 2U; 0124 } else { 0125 failCode |= (check_frequency(dcc1CNT1_CLKSRC_PLL2) << 1U); 0126 } 0127 if (failCode == 0U) { 0128 break; 0129 } 0130 } 0131 /* To avoid MISRA violation 382S 0132 (void)missing for discarded return value */ 0133 failCode = disable_plls(SYS_CLKSRC_PLL1 | SYS_CLKSRC_PLL2); 0134 /* restore CLKCNTL, VCLKR and PENA first */ 0135 TMS570_SYS1.CLKCNTL = (clkCntlSav & 0x000F0100U); 0136 /* restore CLKCNTL, VCLK2R */ 0137 TMS570_SYS1.CLKCNTL = clkCntlSav; 0138 return failCode; 0139 } 0140 0141 /** @fn uint32_t _errata_SSWF021_45_pll1(uint32_t count) 0142 * @brief This handles the errata for PLL1. This function is called in device 0143 * startup 0144 * 0145 * @param[in] count : Number of retries until both PLL1 is locked successfully 0146 * Minimum value recommended is 5 0147 * 0148 * @return 0 = Success (the PLL or both PLLs have successfully locked and then 0149 * been disabled) 0150 * 1 = PLL1 failed to successfully lock in "count" tries 0151 * 2 = PLL2 failed to successfully lock in "count" tries 0152 * 3 = Neither PLL1 nor PLL2 successfully locked in "count" tries 0153 * 4 = The workaround function was not able to disable at least one of 0154 * the PLLs. The most likely reason is that a PLL is already being 0155 * used as a clock source. This can be caused by the workaround 0156 * function being called from the wrong place in the code. 0157 */ 0158 uint32_t _errata_SSWF021_45_pll1(uint32_t count) { 0159 uint32_t failCode, retries, clkCntlSav; 0160 0161 /* save CLKCNTL */ 0162 clkCntlSav = TMS570_SYS1.CLKCNTL; 0163 /* First set VCLK2 = HCLK */ 0164 TMS570_SYS1.CLKCNTL = clkCntlSav & 0x000F0100U; 0165 /* Now set VCLK = HCLK and enable peripherals */ 0166 TMS570_SYS1.CLKCNTL = SYS_CLKCNTRL_PENA; 0167 failCode = 0U; 0168 for (retries = 0U; (retries < count); retries++) { 0169 failCode = 0U; 0170 /* Disable PLL1 */ 0171 failCode = disable_plls(SYS_CLKSRC_PLL1); 0172 if (failCode != 0U) { 0173 break; 0174 } 0175 0176 /* Clear Global Status Register */ 0177 TMS570_SYS1.GLBSTAT = 0x00000301U; 0178 /* Clear the ESM PLL slip flags */ 0179 TMS570_ESM.SR[0U] = ESM_SR1_PLL1SLIP; 0180 /* set PLL1 to OSCIN/1*27/(2*1) */ 0181 TMS570_SYS1.PLLCTL1 = 0x20001A00U; 0182 TMS570_SYS1.PLLCTL2 = 0x3FC0723DU; 0183 TMS570_SYS1.CSDISCLR = SYS_CLKSRC_PLL1; 0184 /* Check for PLL1 valid or PLL1 slip*/ 0185 while (((TMS570_SYS1.CSVSTAT & SYS_CLKSRC_PLL1) == 0U) && 0186 ((TMS570_ESM.SR[0U] & ESM_SR1_PLL1SLIP) == 0U)) { 0187 /* Wait */ 0188 } 0189 /* If PLL1 valid, check the frequency */ 0190 if (((TMS570_ESM.SR[0U] & ESM_SR1_PLL1SLIP) != 0U) || 0191 ((TMS570_SYS1.GLBSTAT & 0x00000300U) != 0U)) { 0192 failCode |= 1U; 0193 } else { 0194 failCode |= check_frequency(dcc1CNT1_CLKSRC_PLL1); 0195 } 0196 if (failCode == 0U) { 0197 break; 0198 } 0199 } 0200 /* To avoid MISRA violation 382S 0201 (void)missing for discarded return value */ 0202 failCode = disable_plls(SYS_CLKSRC_PLL1); 0203 /* restore CLKCNTL, VCLKR and PENA first */ 0204 TMS570_SYS1.CLKCNTL = (clkCntlSav & 0x000F0100U); 0205 /* restore CLKCNTL, VCLK2R */ 0206 TMS570_SYS1.CLKCNTL = clkCntlSav; 0207 return failCode; 0208 } 0209 0210 /** @fn uint32_t _errata_SSWF021_45_pll2(uint32_t count) 0211 * @brief This handles the errata for PLL2. This function is called in device 0212 * startup 0213 * 0214 * @param[in] count : Number of retries until PLL2 is locked successfully 0215 * Minimum value recommended is 5 0216 * 0217 * @return 0 = Success (the PLL or both PLLs have successfully locked and then 0218 * been disabled) 0219 * 1 = PLL1 failed to successfully lock in "count" tries 0220 * 2 = PLL2 failed to successfully lock in "count" tries 0221 * 3 = Neither PLL1 nor PLL2 successfully locked in "count" tries 0222 * 4 = The workaround function was not able to disable at least one of 0223 * the PLLs. The most likely reason is that a PLL is already being 0224 * used as a clock source. This can be caused by the workaround 0225 * function being called from the wrong place in the code. 0226 */ 0227 uint32_t _errata_SSWF021_45_pll2(uint32_t count) { 0228 uint32_t failCode, retries, clkCntlSav; 0229 0230 /* save CLKCNTL */ 0231 clkCntlSav = TMS570_SYS1.CLKCNTL; 0232 /* First set VCLK2 = HCLK */ 0233 TMS570_SYS1.CLKCNTL = clkCntlSav & 0x000F0100U; 0234 /* Now set VCLK = HCLK and enable peripherals */ 0235 TMS570_SYS1.CLKCNTL = SYS_CLKCNTRL_PENA; 0236 failCode = 0U; 0237 for (retries = 0U; (retries < count); retries++) { 0238 failCode = 0U; 0239 /* Disable PLL2 */ 0240 failCode = disable_plls(SYS_CLKSRC_PLL2); 0241 if (failCode != 0U) { 0242 break; 0243 } 0244 0245 /* Clear Global Status Register */ 0246 TMS570_SYS1.GLBSTAT = 0x00000301U; 0247 /* Clear the ESM PLL slip flags */ 0248 TMS570_ESM.SR4 = ESM_SR4_PLL2SLIP; 0249 /* set PLL2 to OSCIN/1*27/(2*1) */ 0250 TMS570_SYS2.PLLCTL3 = 0x20001A00U; 0251 TMS570_SYS1.CSDISCLR = SYS_CLKSRC_PLL2; 0252 /* Check for PLL2 valid or PLL2 slip */ 0253 while (((TMS570_SYS1.CSVSTAT & SYS_CLKSRC_PLL2) == 0U) && 0254 ((TMS570_ESM.SR4 & ESM_SR4_PLL2SLIP) == 0U)) { 0255 /* Wait */ 0256 } 0257 /* If PLL2 valid, check the frequency */ 0258 if (((TMS570_ESM.SR4 & ESM_SR4_PLL2SLIP) != 0U) || 0259 ((TMS570_SYS1.GLBSTAT & 0x00000300U) != 0U)) { 0260 failCode |= 2U; 0261 } else { 0262 failCode |= (check_frequency(dcc1CNT1_CLKSRC_PLL2) << 1U); 0263 } 0264 if (failCode == 0U) { 0265 break; 0266 } 0267 } 0268 /* To avoid MISRA violation 382S 0269 (void)missing for discarded return value */ 0270 failCode = disable_plls(SYS_CLKSRC_PLL2); 0271 /* restore CLKCNTL, VCLKR and PENA first */ 0272 TMS570_SYS1.CLKCNTL = (clkCntlSav & 0x000F0100U); 0273 /* restore CLKCNTL, VCLK2R */ 0274 TMS570_SYS1.CLKCNTL = clkCntlSav; 0275 return failCode; 0276 } 0277 0278 /** @fn uint32_t check_frequency(uint32_t cnt1_clksrc) 0279 * @brief This function checks for the PLL frequency. 0280 * 0281 * @param[in] cnt1_clksrc : Clock source for Counter1 0282 * 0U - PLL1 (clock source 0) 0283 * 1U - PLL2 (clock source 1) 0284 * 0285 * @return DCC Error status 0286 * 0 - DCC error has not occurred 0287 * 1 - DCC error has occurred 0288 */ 0289 static uint32_t check_frequency(uint32_t cnt1_clksrc) { 0290 /* Setup DCC1 */ 0291 /** DCC1 Global Control register configuration */ 0292 TMS570_DCC1.GCTRL = 0293 (uint32_t)0x5U | /** Disable DCC1 */ 0294 (uint32_t)((uint32_t)0x5U << 4U) | /** No Error Interrupt */ 0295 (uint32_t)((uint32_t)0xAU << 8U) | /** Single Shot mode */ 0296 (uint32_t)((uint32_t)0x5U << 12U); /** No Done Interrupt */ 0297 /* Clear ERR and DONE bits */ 0298 TMS570_DCC1.STAT = 3U; 0299 /** DCC1 Clock0 Counter Seed value configuration */ 0300 TMS570_DCC1.CNT0SEED = 68U; 0301 /** DCC1 Clock0 Valid Counter Seed value configuration */ 0302 TMS570_DCC1.VALID0SEED = 4U; 0303 /** DCC1 Clock1 Counter Seed value configuration */ 0304 TMS570_DCC1.CNT1SEED = 972U; 0305 /** DCC1 Clock1 Source 1 Select */ 0306 TMS570_DCC1.CNT1CLKSRC = 0307 (uint32_t)((uint32_t)10U << 12U) | /** DCC Enable / Disable Key */ 0308 (uint32_t)cnt1_clksrc; /** DCC1 Clock Source 1 */ 0309 0310 TMS570_DCC1.CNT0CLKSRC = 0311 (uint32_t)DCC1_CNT0_OSCIN; /** DCC1 Clock Source 0 */ 0312 0313 /** DCC1 Global Control register configuration */ 0314 TMS570_DCC1.GCTRL = 0315 (uint32_t)0xAU | /** Enable DCC1 */ 0316 (uint32_t)((uint32_t)0x5U << 4U) | /** No Error Interrupt */ 0317 (uint32_t)((uint32_t)0xAU << 8U) | /** Single Shot mode */ 0318 (uint32_t)((uint32_t)0x5U << 12U); /** No Done Interrupt */ 0319 while (TMS570_DCC1.STAT == 0U) { 0320 /* Wait */ 0321 } 0322 return (TMS570_DCC1.STAT & 0x01U); 0323 } 0324 0325 /** @fn uint32_t disable_plls(uint32_t plls) 0326 * @brief This function disables plls and clears the respective ESM flags. 0327 * 0328 * @param[in] plls : Clock source for Counter1 0329 * 2U - PLL1 0330 * 40U - PLL2 0331 * 0332 * @return failCode 0333 * 0 = Success (the PLL or both PLLs have successfully locked and 0334 * then been disabled) 0335 * 4 = The workaround function was not able to disable at least one 0336 * of the PLLs. The most likely reason is that a PLL is already being 0337 * used as a clock source. This can be caused by the workaround 0338 * function being called from the wrong place in the code. 0339 */ 0340 static uint32_t disable_plls(uint32_t plls) { 0341 uint32_t timeout, failCode; 0342 0343 TMS570_SYS1.CSDISSET = plls; 0344 failCode = 0U; 0345 timeout = 0x10U; 0346 timeout--; 0347 while (((TMS570_SYS1.CSVSTAT & (plls)) != 0U) && (timeout != 0U)) { 0348 /* Clear ESM and GLBSTAT PLL slip flags */ 0349 TMS570_SYS1.GLBSTAT = 0x00000300U; 0350 0351 if ((plls & SYS_CLKSRC_PLL1) == SYS_CLKSRC_PLL1) { 0352 TMS570_ESM.SR[0U] = ESM_SR1_PLL1SLIP; 0353 } 0354 if ((plls & SYS_CLKSRC_PLL2) == SYS_CLKSRC_PLL2) { 0355 TMS570_ESM.SR4 = ESM_SR4_PLL2SLIP; 0356 } 0357 timeout--; 0358 /* Wait */ 0359 } 0360 if (timeout == 0U) { 0361 failCode = 4U; 0362 } else { 0363 failCode = 0U; 0364 } 0365 return failCode; 0366 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |