]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - psdk_cust/pdk_k2g_1_0_1_2_eng/packages/ti/board/src/evmAM572x/iodelay_config.c
Merge pull request #1 in PASDK/pasdk_sr from PASDK-318-input-task-code-repetition...
[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)
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();
194 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
195                      uint32_t padArraySize)
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     }
260 static void boardPadIoIsolation(void)
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;
310 static void boardPadIoDeIsolation(void)
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;
354 static uint32_t calculateConfigRegister(uint32_t aDelay,
355                                         uint32_t gDelay,
356                                         uint32_t cpde,
357                                         uint32_t fpde)
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;
384 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue)
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;