[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_2_eng / packages / ti / board / src / evmAM572x / iodelay_config.c
1 /**
2 * \file sbl_main.c
3 *
4 * \brief This file contain main function, call the Soc Init
5 * functions & slave core boot-up functions in sequence.
6 *
7 */
9 /*
10 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the
22 * distribution.
23 *
24 * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 */
42 #include <ti/csl/cslr_device.h>
43 #include <ti/csl/soc/am572x/src/cslr_device_prm.h>
44 #include <stdint.h>
45 #include "iodelay_config.h"
47 /**
48 * \brief This function configures the SoC PAD Mux as given by Pinmux tool
49 * with Virtual and Manual mode delays.
50 *
51 * \param pPadCfgData Pointer to the global data structure.
52 *
53 */
54 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
55 #pragma CODE_SECTION (BoardCtrlPadMux, "BOARD_IO_DELAY_CODE");
56 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
57 uint32_t padArraySize);
58 #else
59 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
60 uint32_t padArraySize) __attribute__((section("BOARD_IO_DELAY_CODE")));
61 #endif
63 /**
64 * \brief This function calculates the final value to be written to
65 * configuration register using aDelay and gDelay values.
66 *
67 * \param aDelay Value of A delay.
68 * \param gDelay Value of G Delay.
69 * \param cpde CPDE Value as previously calculated
70 * \param fpde FPDE value as previously calculated
71 *
72 * \return configRegValue Calculated Config Register Value
73 */
74 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
75 #pragma CODE_SECTION (calculateConfigRegister, "BOARD_IO_DELAY_CODE");
76 static uint32_t calculateConfigRegister(uint32_t aDelay,
77 uint32_t gDelay,
78 uint32_t cpde,
79 uint32_t fpde);
80 #else
81 static uint32_t calculateConfigRegister(uint32_t aDelay,
82 uint32_t gDelay,
83 uint32_t cpde,
84 uint32_t fpde) __attribute__((section("BOARD_IO_DELAY_CODE")));
85 #endif
87 /**
88 * \brief This function calculates the delay value for CPDE and FDPE.
89 *
90 * \param configRegOffset Offset Address of Config Register.
91 * Possible Values:CONFIG_REG_3/CONFIG_REG_4
92 * \param divisorValue Value of the divisor
93 * Possible Values: 88 for CONFIG_REG_3
94 * 264 for CONFIG_REG_4
95 *
96 * \return delayVal Calculated Delay Value
97 */
98 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
99 #pragma CODE_SECTION (calculateDelay, "BOARD_IO_DELAY_CODE");
100 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue);
101 #else
102 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue) __attribute__((section("BOARD_IO_DELAY_CODE")));
103 #endif
105 /**
106 * \brief This function initiates the steps required to perform IO isolation
107 * during IO Delay recalibration sequence.
108 *
109 */
110 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
111 #pragma CODE_SECTION (boardPadIoIsolation, "BOARD_IO_DELAY_CODE");
112 static void boardPadIoIsolation(void);
113 #else
114 static void boardPadIoIsolation(void) __attribute__((section("BOARD_IO_DELAY_CODE")));
115 #endif
117 /**
118 * \brief This function initiates the steps required to perform IO de-isolation
119 * during IO Delay recalibration sequence.
120 */
121 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
122 #pragma CODE_SECTION (boardPadIoDeIsolation, "BOARD_IO_DELAY_CODE");
123 static void boardPadIoDeIsolation(void);
124 #else
125 static void boardPadIoDeIsolation(void) __attribute__((section("BOARD_IO_DELAY_CODE")));
126 #endif
128 #define HW_WR_REG32(addr, data) *(unsigned int*)(addr) =(unsigned int)(data)
130 /* ISOIN Field for CTRL_CORE_SMA_SW_0 */
131 #define CSL_CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO_SHIFT (2U)
132 #define CSL_CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO_MASK (0x00000004U)
134 #define CSL_CONFIG_REG_0_ROM_READ_MASK (0x00000002U)
135 #define CSL_CONFIG_REG_0_ROM_READ_SHIFT (1U)
137 /* Lock and Unlock values for Global lock : CONFIG_REG_8 */
138 #define CONFIG_REG_8_LOCK_GLOBAL_LOCK (0x0000AAABU)
139 #define CONFIG_REG_8_UNLOCK_GLOBAL_LOCK (0x0000AAAAU)
141 /* Lock and Unlock values for MMR_LOCK1 */
142 #define LOCK_MMR_LOCK1 (0x1A1C8144U)
143 #define UNLOCK_MMR_LOCK1 (0x2FF1AC2BU)
145 /* Lock and Unlock values for MMR_LOCK5 */
146 #define LOCK_MMR_LOCK5 (0x143F832CU)
147 #define UNLOCK_MMR_LOCK5 (0x6F361E05U)
149 /* Reference clock period for sysclk1 of 20 MHz */
150 #define REFCLK_PERIOD_SYSCLK1_20MHZ (0x00002710U)
152 /* Reference clock period for L4 ICLK of 66.5 MHz */
153 #define REFCLK_PERIOD_L4ICLK_66_5_MHZ (0x000005DEU)
155 void BoardCtrlPadIoDelayConfig(const boardPadDelayCfg_t *pPadCfgData, uint32_t padArraySize)
156 {
157 CSL_IodelayconfigRegs *ioDelayCfg =
158 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
160 /* Unlock the global lock */
161 CSL_FINS(ioDelayCfg->CONFIG_REG_8, IODELAYCONFIG_CONFIG_REG_8_GLOBAL_LOCK_BIT,
162 CONFIG_REG_8_UNLOCK_GLOBAL_LOCK);
164 /*
165 * Update config_reg2 based on actual sysclk1 frequency.
166 * Take sysclock1 period in ps and divide by 5 and write to register.
167 * This ensures calibration logic assumes the correct clock reference.
168 */
169 CSL_FINS(ioDelayCfg->CONFIG_REG_2, IODELAYCONFIG_CONFIG_REG_2_REFCLK_PERIOD,
170 REFCLK_PERIOD_L4ICLK_66_5_MHZ);
172 /* Trigger the recalibration */
173 CSL_FINS(ioDelayCfg->CONFIG_REG_0, IODELAYCONFIG_CONFIG_REG_0_CALIBRATION_START,
174 0x1U);
176 /*
177 * Read CALIBRATION_START until it is read as 0,
178 * indicating recalibration is complete.
179 */
180 while ((uint32_t) 0U != CSL_FEXT(ioDelayCfg->CONFIG_REG_0,
181 IODELAYCONFIG_CONFIG_REG_0_CALIBRATION_START))
182 {}
184 /* Begin the Isolation sequence to Isolate all the IOs */
185 boardPadIoIsolation();
187 /* Configure PAD mux for SoC along with Virtual and Manual Mode Delays */
188 BoardCtrlPadMux(pPadCfgData, padArraySize);
190 /* Begin the DeIsolation sequence to remove the Isolation on the IOs. */
191 boardPadIoDeIsolation();
192 }
194 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
195 uint32_t padArraySize)
196 {
197 uint32_t index = 0U;
198 uint32_t cpde, fpde, configRegValue, modeSelect;
199 uint32_t address = 0U;
201 CSL_IodelayconfigRegs *ioDelayCfg =
202 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
204 cpde = calculateDelay(ioDelayCfg->CONFIG_REG_3, (uint32_t) 88);
205 fpde = calculateDelay(ioDelayCfg->CONFIG_REG_4, (uint32_t) 264);
207 for (index = 0; index < padArraySize; index++)
208 {
209 address = (CSL_MPU_CTRL_MODULE_CORE_REGS +
210 ((uint32_t) (pPadCfgData + index)->offset));
211 HW_WR_REG32(address, (pPadCfgData + index)->regVal);
213 modeSelect = (pPadCfgData + index)->regVal &
214 CSL_CONTROL_CORE_PAD_IO_PAD_GPMC_AD0_GPMC_AD0_MODESELECT_MASK;
216 if ((0U != modeSelect) &&
217 (0U != (pPadCfgData + index)->delayConfigIn.offset))
218 {
219 configRegValue = calculateConfigRegister(
220 (pPadCfgData + index)->delayConfigIn.aDelay,
221 (pPadCfgData + index)->delayConfigIn.gDelay,
222 cpde,
223 fpde);
225 address = (CSL_MPU_DELAYLINE_REGS +
226 ((uint32_t) (pPadCfgData + index)->delayConfigIn.offset));
227 HW_WR_REG32(address, configRegValue);
229 }
230 if ((0U != modeSelect) &&
231 (0U != (pPadCfgData + index)->delayConfigOen.offset))
232 {
233 configRegValue = calculateConfigRegister(
234 (pPadCfgData + index)->delayConfigOen.aDelay,
235 (pPadCfgData + index)->delayConfigOen.gDelay,
236 cpde,
237 fpde);
239 address = (CSL_MPU_DELAYLINE_REGS +
240 ((uint32_t) (pPadCfgData + index)->delayConfigOen.offset));
241 HW_WR_REG32(address, configRegValue);
242 }
244 if ((0U != modeSelect) &&
245 (0U != (pPadCfgData + index)->delayConfigOut.offset))
246 {
247 configRegValue = calculateConfigRegister(
248 (pPadCfgData + index)->delayConfigOut.aDelay,
249 (pPadCfgData + index)->delayConfigOut.gDelay,
250 cpde,
251 fpde);
253 address = (CSL_MPU_DELAYLINE_REGS +
254 ((uint32_t) (pPadCfgData + index)->delayConfigOut.offset));
255 HW_WR_REG32(address, configRegValue);
256 }
257 }
258 }
260 static void boardPadIoIsolation(void)
261 {
262 volatile uint32_t dummyRead = 0U;
264 CSL_control_coreRegs *ctrlCoreRegs =
265 (CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS;
267 CSL_IodelayconfigRegs *ioDelayCfg =
268 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
270 CSL_device_prmRegs *devPrm =
271 (CSL_device_prmRegs *) CSL_MPU_DEVICE_PRM_REGS;
273 /*
274 * Isolate all the IO.
275 */
276 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
277 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_OVERRIDE);
279 while ((uint32_t) 0x1U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
280 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS))
281 {}
283 CSL_FINS(ctrlCoreRegs->SMA_SW_0,
284 CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO, 0x1U);
286 dummyRead = CSL_FEXT(ctrlCoreRegs->SMA_SW_0,
287 CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO);
289 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
290 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_NOOVERRIDE);
292 while((uint32_t) 0x0U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
293 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS));
295 /* Update delay mechanism for each IO with recalibrated values */
296 CSL_FINS(ioDelayCfg->CONFIG_REG_0, CONFIG_REG_0_ROM_READ, 0x1U);
298 /*
299 * Read ROM_READ until it is read as 0,
300 * indicating reload is complete.
301 */
302 while ((uint32_t) 0U != CSL_FEXT(ioDelayCfg->CONFIG_REG_0,
303 CONFIG_REG_0_ROM_READ))
304 {}
306 /* Dummy read to remove compiler warning */
307 dummyRead = dummyRead;
308 }
310 static void boardPadIoDeIsolation(void)
311 {
312 volatile uint32_t dummyRead = 0U;
314 CSL_control_coreRegs *ctrlCoreRegs =
315 (CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS;
317 CSL_IodelayconfigRegs *ioDelayCfg =
318 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
320 CSL_device_prmRegs *devPrm =
321 (CSL_device_prmRegs *) CSL_MPU_DEVICE_PRM_REGS;
323 /*
324 * Remove all IOs from isolation.
325 */
326 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
327 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_OVERRIDE);
329 while ((uint32_t) 0x1U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
330 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS))
331 {}
333 CSL_FINS(ctrlCoreRegs->SMA_SW_0, CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO,
334 0x0U);
336 dummyRead = CSL_FEXT(ctrlCoreRegs->SMA_SW_0,
337 CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO);
339 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
340 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_NOOVERRIDE);
342 while ((uint32_t) 0x0U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
343 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS))
344 {}
346 /* Lock the global lock */
347 CSL_FINS(ioDelayCfg->CONFIG_REG_8, IODELAYCONFIG_CONFIG_REG_8_GLOBAL_LOCK_BIT,
348 CONFIG_REG_8_LOCK_GLOBAL_LOCK);
350 /* Dummy read to remove compiler warning */
351 dummyRead = dummyRead;
352 }
354 static uint32_t calculateConfigRegister(uint32_t aDelay,
355 uint32_t gDelay,
356 uint32_t cpde,
357 uint32_t fpde)
358 {
359 uint32_t gDelayCoarse, gDelayFine, aDelayCoarse, aDelayFine;
360 uint32_t coarseElements, fineElements, totalDelay;
361 uint32_t finalConfigRegValue = 0U;
363 gDelayCoarse = gDelay / 920U;
364 gDelayFine = ((gDelay % 920U) * 10U) / 60U;
366 aDelayCoarse = aDelay / cpde;
367 aDelayFine = ((aDelay % cpde) * 10U) / fpde;
369 coarseElements = gDelayCoarse + aDelayCoarse;
370 fineElements = (gDelayFine + aDelayFine) / 10U;
372 if (22U < fineElements)
373 {
374 totalDelay = (coarseElements * cpde) + (fineElements * fpde);
375 coarseElements = totalDelay / cpde;
376 fineElements = (totalDelay % cpde) / fpde;
377 }
379 finalConfigRegValue = (0x29400U ^ (coarseElements << 5U)) + fineElements;
381 return finalConfigRegValue;
382 }
384 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue)
385 {
386 uint32_t refclkPeriod, delayCount, refCount, delayVal;
387 CSL_IodelayconfigRegs *ioDelayCfg =
388 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
390 refclkPeriod = CSL_FEXT(ioDelayCfg->CONFIG_REG_2,
391 IODELAYCONFIG_CONFIG_REG_2_REFCLK_PERIOD);
393 delayCount = CSL_FEXT(CSL_MPU_DELAYLINE_REGS + configRegOffset,
394 IODELAYCONFIG_CONFIG_REG_3_COARSE_DELAY_COUNT);
396 refCount = CSL_FEXT(CSL_MPU_DELAYLINE_REGS + configRegOffset,
397 IODELAYCONFIG_CONFIG_REG_3_COARSE_REF_COUNT);
399 delayVal = (uint32_t)
400 (((uint64_t) 10 * (uint64_t) (refCount) *
401 (uint64_t) (refclkPeriod)) /
402 ((uint64_t) 2 * (uint64_t) (delayCount) *
403 (uint64_t) (divisorValue)));
405 return delayVal;
406 }