[processor-sdk/performance-audio-sr.git] / pdk_k2g_1_0_1_0_eng / packages / ti / board / src / idkAM571x / 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/am571x/src/cslr_device_prm.h>
44 #include <stdint.h>
45 #include "iodelay_config.h"
47 extern const boardPadDelayAltGpCfg_t altPad[];
49 /**
50 * \brief This function configures the SoC PAD Mux as given by Pinmux tool
51 * with Virtual and Manual mode delays.
52 *
53 * \param pPadCfgData Pointer to the global data structure.
54 *
55 */
56 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
57 #pragma CODE_SECTION (BoardCtrlPadMux, "BOARD_IO_DELAY_CODE");
58 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
59 uint32_t padArraySize);
60 #else
61 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
62 uint32_t padArraySize) __attribute__((section("BOARD_IO_DELAY_CODE")));
63 #endif
65 /**
66 * \brief This function calculates the final value to be written to
67 * configuration register using aDelay and gDelay values.
68 *
69 * \param aDelay Value of A delay.
70 * \param gDelay Value of G Delay.
71 * \param cpde CPDE Value as previously calculated
72 * \param fpde FPDE value as previously calculated
73 *
74 * \return configRegValue Calculated Config Register Value
75 */
76 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
77 #pragma CODE_SECTION (calculateConfigRegister, "BOARD_IO_DELAY_CODE");
78 static uint32_t calculateConfigRegister(uint32_t aDelay,
79 uint32_t gDelay,
80 uint32_t cpde,
81 uint32_t fpde);
82 #else
83 static uint32_t calculateConfigRegister(uint32_t aDelay,
84 uint32_t gDelay,
85 uint32_t cpde,
86 uint32_t fpde) __attribute__((section("BOARD_IO_DELAY_CODE")));
87 #endif
89 /**
90 * \brief This function calculates the delay value for CPDE and FDPE.
91 *
92 * \param configRegOffset Offset Address of Config Register.
93 * Possible Values:CONFIG_REG_3/CONFIG_REG_4
94 * \param divisorValue Value of the divisor
95 * Possible Values: 88 for CONFIG_REG_3
96 * 264 for CONFIG_REG_4
97 *
98 * \return delayVal Calculated Delay Value
99 */
100 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
101 #pragma CODE_SECTION (calculateDelay, "BOARD_IO_DELAY_CODE");
102 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue);
103 #else
104 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue) __attribute__((section("BOARD_IO_DELAY_CODE")));
105 #endif
107 /**
108 * \brief This function initiates the steps required to perform IO isolation
109 * during IO Delay recalibration sequence.
110 *
111 */
112 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
113 #pragma CODE_SECTION (boardPadIoIsolation, "BOARD_IO_DELAY_CODE");
114 static void boardPadIoIsolation(void);
115 #else
116 static void boardPadIoIsolation(void) __attribute__((section("BOARD_IO_DELAY_CODE")));
117 #endif
119 /**
120 * \brief This function initiates the steps required to perform IO de-isolation
121 * during IO Delay recalibration sequence.
122 */
123 #if defined(_TMS320C6X) || defined(__TI_ARM_V7M4__)
124 #pragma CODE_SECTION (boardPadIoDeIsolation, "BOARD_IO_DELAY_CODE");
125 static void boardPadIoDeIsolation(void);
126 #else
127 static void boardPadIoDeIsolation(void) __attribute__((section("BOARD_IO_DELAY_CODE")));
128 #endif
130 #define HW_WR_REG32(addr, data) *(unsigned int*)(addr) =(unsigned int)(data)
132 /* ISOIN Field for CTRL_CORE_SMA_SW_0 */
133 #define CSL_CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO_SHIFT (2U)
134 #define CSL_CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO_MASK (0x00000004U)
136 #define CSL_CONFIG_REG_0_ROM_READ_MASK (0x00000002U)
137 #define CSL_CONFIG_REG_0_ROM_READ_SHIFT (1U)
139 /* Lock and Unlock values for Global lock : CONFIG_REG_8 */
140 #define CONFIG_REG_8_LOCK_GLOBAL_LOCK (0x0000AAABU)
141 #define CONFIG_REG_8_UNLOCK_GLOBAL_LOCK (0x0000AAAAU)
143 /* Lock and Unlock values for MMR_LOCK1 */
144 #define LOCK_MMR_LOCK1 (0x1A1C8144U)
145 #define UNLOCK_MMR_LOCK1 (0x2FF1AC2BU)
147 /* Lock and Unlock values for MMR_LOCK5 */
148 #define LOCK_MMR_LOCK5 (0x143F832CU)
149 #define UNLOCK_MMR_LOCK5 (0x6F361E05U)
151 /* Reference clock period for sysclk1 of 20 MHz */
152 #define REFCLK_PERIOD_SYSCLK1_20MHZ (0x00002710U)
154 /* Reference clock period for L4 ICLK of 66.5 MHz */
155 #define REFCLK_PERIOD_L4ICLK_66_5_MHZ (0x000005DEU)
157 void BoardCtrlPadIoDelayConfig(const boardPadDelayCfg_t *pPadCfgData, uint32_t padArraySize)
158 {
159 CSL_IodelayconfigRegs *ioDelayCfg =
160 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
162 /* Unlock the global lock */
163 CSL_FINS(ioDelayCfg->CONFIG_REG_8, IODELAYCONFIG_CONFIG_REG_8_GLOBAL_LOCK_BIT,
164 CONFIG_REG_8_UNLOCK_GLOBAL_LOCK);
166 /*
167 * Update config_reg2 based on actual sysclk1 frequency.
168 * Take sysclock1 period in ps and divide by 5 and write to register.
169 * This ensures calibration logic assumes the correct clock reference.
170 */
171 CSL_FINS(ioDelayCfg->CONFIG_REG_2, IODELAYCONFIG_CONFIG_REG_2_REFCLK_PERIOD,
172 REFCLK_PERIOD_L4ICLK_66_5_MHZ);
174 /* Trigger the recalibration */
175 CSL_FINS(ioDelayCfg->CONFIG_REG_0, IODELAYCONFIG_CONFIG_REG_0_CALIBRATION_START,
176 0x1U);
178 /*
179 * Read CALIBRATION_START until it is read as 0,
180 * indicating recalibration is complete.
181 */
182 while ((uint32_t) 0U != CSL_FEXT(ioDelayCfg->CONFIG_REG_0,
183 IODELAYCONFIG_CONFIG_REG_0_CALIBRATION_START))
184 {}
186 /* Begin the Isolation sequence to Isolate all the IOs */
187 boardPadIoIsolation();
189 /* Configure PAD mux for SoC along with Virtual and Manual Mode Delays */
190 BoardCtrlPadMux(pPadCfgData, padArraySize);
192 /* Begin the DeIsolation sequence to remove the Isolation on the IOs. */
193 boardPadIoDeIsolation();
194 }
196 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
197 uint32_t padArraySize)
198 {
199 uint32_t index = 0U;
200 uint32_t cpde, fpde, configRegValue, modeSelect;
201 uint32_t address = 0U;
202 const boardPadDelayAltGpCfg_t *pAltPadCfgData;
204 CSL_IodelayconfigRegs *ioDelayCfg =
205 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
207 cpde = calculateDelay(ioDelayCfg->CONFIG_REG_3, (uint32_t) 88);
208 fpde = calculateDelay(ioDelayCfg->CONFIG_REG_4, (uint32_t) 264);
210 for (index = 0; index < padArraySize; index++)
211 {
212 address = (CSL_MPU_CTRL_MODULE_CORE_REGS +
213 ((uint32_t) (pPadCfgData + index)->offset));
214 HW_WR_REG32(address, (pPadCfgData + index)->regVal);
216 modeSelect = (pPadCfgData + index)->regVal &
217 CSL_CONTROL_CORE_PAD_IO_PAD_GPMC_AD0_GPMC_AD0_MODESELECT_MASK;
219 if ((0U != modeSelect) &&
220 (0U != (pPadCfgData + index)->delayConfigIn.offset))
221 {
222 configRegValue = calculateConfigRegister(
223 (pPadCfgData + index)->delayConfigIn.aDelay,
224 (pPadCfgData + index)->delayConfigIn.gDelay,
225 cpde,
226 fpde);
228 address = (CSL_MPU_DELAYLINE_REGS +
229 ((uint32_t) (pPadCfgData + index)->delayConfigIn.offset));
230 HW_WR_REG32(address, configRegValue);
232 }
233 if ((0U != modeSelect) &&
234 (0U != (pPadCfgData + index)->delayConfigOen.offset))
235 {
236 configRegValue = calculateConfigRegister(
237 (pPadCfgData + index)->delayConfigOen.aDelay,
238 (pPadCfgData + index)->delayConfigOen.gDelay,
239 cpde,
240 fpde);
242 address = (CSL_MPU_DELAYLINE_REGS +
243 ((uint32_t) (pPadCfgData + index)->delayConfigOen.offset));
244 HW_WR_REG32(address, configRegValue);
245 }
247 if ((0U != modeSelect) &&
248 (0U != (pPadCfgData + index)->delayConfigOut.offset))
249 {
250 configRegValue = calculateConfigRegister(
251 (pPadCfgData + index)->delayConfigOut.aDelay,
252 (pPadCfgData + index)->delayConfigOut.gDelay,
253 cpde,
254 fpde);
256 address = (CSL_MPU_DELAYLINE_REGS +
257 ((uint32_t) (pPadCfgData + index)->delayConfigOut.offset));
258 HW_WR_REG32(address, configRegValue);
259 }
260 }
262 /* Configure the alternate pinmux if it is enabled. */
263 #if defined(BOARD_PAD_DELAY_ALT_GRP_ENABLE)
264 pAltPadCfgData = altPad;
265 padArraySize = boardAltPadGetSize();
266 for (index = 0; index < padArraySize; index++)
267 {
268 HW_WR_REG32((pAltPadCfgData + index)->regAddr,
269 (pAltPadCfgData + index)->regVal);
270 }
271 #endif
272 }
274 static void boardPadIoIsolation(void)
275 {
276 volatile uint32_t dummyRead = 0U;
278 CSL_control_coreRegs *ctrlCoreRegs =
279 (CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS;
281 CSL_IodelayconfigRegs *ioDelayCfg =
282 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
284 CSL_device_prmRegs *devPrm =
285 (CSL_device_prmRegs *) CSL_MPU_DEVICE_PRM_REGS;
287 /*
288 * Isolate all the IO.
289 */
290 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
291 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_OVERRIDE);
293 while ((uint32_t) 0x1U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
294 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS))
295 {}
297 CSL_FINS(ctrlCoreRegs->SMA_SW_0,
298 CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO, 0x1U);
300 dummyRead = CSL_FEXT(ctrlCoreRegs->SMA_SW_0,
301 CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO);
303 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
304 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_NOOVERRIDE);
306 while((uint32_t) 0x0U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
307 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS));
309 /* Update delay mechanism for each IO with recalibrated values */
310 CSL_FINS(ioDelayCfg->CONFIG_REG_0, CONFIG_REG_0_ROM_READ, 0x1U);
312 /*
313 * Read ROM_READ until it is read as 0,
314 * indicating reload is complete.
315 */
316 while ((uint32_t) 0U != CSL_FEXT(ioDelayCfg->CONFIG_REG_0,
317 CONFIG_REG_0_ROM_READ))
318 {}
320 /* Dummy read to remove compiler warning */
321 dummyRead = dummyRead;
322 }
324 static void boardPadIoDeIsolation(void)
325 {
326 volatile uint32_t dummyRead = 0U;
328 CSL_control_coreRegs *ctrlCoreRegs =
329 (CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS;
331 CSL_IodelayconfigRegs *ioDelayCfg =
332 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
334 CSL_device_prmRegs *devPrm =
335 (CSL_device_prmRegs *) CSL_MPU_DEVICE_PRM_REGS;
336 /*
337 * Remove all IOs from isolation.
338 */
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_OVERRIDE);
342 while ((uint32_t) 0x1U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
343 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS))
344 {}
346 CSL_FINS(ctrlCoreRegs->SMA_SW_0, CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO,
347 0x0U);
349 dummyRead = CSL_FEXT(ctrlCoreRegs->SMA_SW_0,
350 CONTROL_CORE_SMA_SW_0_SMA_SW_0_ISO);
352 CSL_FINS(devPrm->PRM_IO_PMCTRL_REG, DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE,
353 CSL_DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_OVERRIDE_NOOVERRIDE);
355 while ((uint32_t) 0x0U != CSL_FEXT(devPrm->PRM_IO_PMCTRL_REG,
356 DEVICE_PRM_PRM_IO_PMCTRL_REG_ISOCLK_STATUS))
357 {}
359 /* Lock the global lock */
360 CSL_FINS(ioDelayCfg->CONFIG_REG_8, IODELAYCONFIG_CONFIG_REG_8_GLOBAL_LOCK_BIT,
361 CONFIG_REG_8_LOCK_GLOBAL_LOCK);
363 /* Dummy read to remove compiler warning */
364 dummyRead = dummyRead;
365 }
367 static uint32_t calculateConfigRegister(uint32_t aDelay,
368 uint32_t gDelay,
369 uint32_t cpde,
370 uint32_t fpde)
371 {
372 uint32_t gDelayCoarse, gDelayFine, aDelayCoarse, aDelayFine;
373 uint32_t coarseElements, fineElements, totalDelay;
374 uint32_t finalConfigRegValue = 0U;
376 gDelayCoarse = gDelay / 920U;
377 gDelayFine = ((gDelay % 920U) * 10U) / 60U;
379 aDelayCoarse = aDelay / cpde;
380 aDelayFine = ((aDelay % cpde) * 10U) / fpde;
382 coarseElements = gDelayCoarse + aDelayCoarse;
383 fineElements = (gDelayFine + aDelayFine) / 10U;
385 if (22U < fineElements)
386 {
387 totalDelay = (coarseElements * cpde) + (fineElements * fpde);
388 coarseElements = totalDelay / cpde;
389 fineElements = (totalDelay % cpde) / fpde;
390 }
392 finalConfigRegValue = (0x29400U ^ (coarseElements << 5U)) + fineElements;
394 return finalConfigRegValue;
395 }
397 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue)
398 {
399 uint32_t refclkPeriod, delayCount, refCount, delayVal;
400 CSL_IodelayconfigRegs *ioDelayCfg =
401 (CSL_IodelayconfigRegs *) CSL_MPU_DELAYLINE_REGS;
403 refclkPeriod = CSL_FEXT(ioDelayCfg->CONFIG_REG_2,
404 IODELAYCONFIG_CONFIG_REG_2_REFCLK_PERIOD);
406 delayCount = CSL_FEXT(CSL_MPU_DELAYLINE_REGS + configRegOffset,
407 IODELAYCONFIG_CONFIG_REG_3_COARSE_DELAY_COUNT);
409 refCount = CSL_FEXT(CSL_MPU_DELAYLINE_REGS + configRegOffset,
410 IODELAYCONFIG_CONFIG_REG_3_COARSE_REF_COUNT);
412 delayVal = (uint32_t)
413 (((uint64_t) 10 * (uint64_t) (refCount) *
414 (uint64_t) (refclkPeriod)) /
415 ((uint64_t) 2 * (uint64_t) (delayCount) *
416 (uint64_t) (divisorValue)));
418 return delayVal;
419 }