]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pdk_k2g_1_0_1/packages/ti/board/src/idkAM571x/iodelay_config.c
Add alpha files for car
[processor-sdk/performance-audio-sr.git] / pdk_k2g_1_0_1 / 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)
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();
196 void BoardCtrlPadMux(const boardPadDelayCfg_t *pPadCfgData,
197                      uint32_t padArraySize)
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
274 static void boardPadIoIsolation(void)
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;
324 static void boardPadIoDeIsolation(void)
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;
367 static uint32_t calculateConfigRegister(uint32_t aDelay,
368                                         uint32_t gDelay,
369                                         uint32_t cpde,
370                                         uint32_t fpde)
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;
397 static uint32_t calculateDelay(uint32_t configRegOffset, uint32_t divisorValue)
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;