]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/board/src/j784s4_evm/board_utils.c
[OSAL]: Added testcase for task sub module
[processor-sdk/pdk.git] / packages / ti / board / src / j784s4_evm / board_utils.c
1 /******************************************************************************
2  * Copyright (c) 2022 Texas Instruments Incorporated - http://www.ti.com
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  *****************************************************************************/
34 /**
35  *  \file   board_utils.c
36  *
37  *  \brief  Implements multiple board utility functions
38  *
39  */
41 #include <stdio.h>
42 #include <string.h>
43 #include <ti/csl/arch/csl_arch.h>
44 #include "board_internal.h"
45 #include "board_utils.h"
46 #include "board_cfg.h"
47 #include <ti/drv/mmcsd/MMCSD.h>
48 #include <ti/drv/mmcsd/soc/MMCSD_soc.h>
50 Board_DetectCfg_t  gBoardDetCfg[BOARD_ID_MAX_BOARDS] =
51  {{BOARD_COMMON_EEPROM_I2C_INST, BOARD_GESI_EEPROM_SLAVE_ADDR, BOARD_SOC_DOMAIN_WKUP, "J7X-GESI-EXP"},
52   {BOARD_CSI2_EEPROM_I2C_INST, BOARD_CSI2_EEPROM_SLAVE_ADDR, BOARD_SOC_DOMAIN_MAIN, "J7X-FUSION2-CSI"},
53   {BOARD_COMMON_EEPROM_I2C_INST, BOARD_ENET_EEPROM_SLAVE_ADDR, BOARD_SOC_DOMAIN_WKUP, "J7X-VSC8514-ETH"},
54   {BOARD_COMMON_EEPROM_I2C_INST, BOARD_CP_EEPROM_SLAVE_ADDR, BOARD_SOC_DOMAIN_WKUP, "J784S4X-EVM"}};
56 Board_I2cInitCfg_t gBoardI2cInitCfg = {0, BOARD_SOC_DOMAIN_MAIN, 0};
57 Board_initParams_t gBoardInitParams = {BOARD_UART_INSTANCE, BOARD_UART_SOC_DOMAIN, BOARD_PSC_DEVICE_MODE_NONEXCLUSIVE,
58                                        BOARD_MAIN_CLOCK_GROUP_ALL, BOARD_MCU_CLOCK_GROUP_ALL};
60 /**
61  *  \brief    Function to configure SD card voltage control gpio configuration.
62  *
63  *  \param    gpioValue [IN] GPIO pin value.
64  *            1 for GPIO pin high
65  *            0 for GPIO pin low
66  *
67  *  \return   BOARD_SOK in case of success or appropriate error code
68  *
69  */
70 static void Board_sdVoltageCtrlGpioCfg(uint8_t gpioValue)
71 {
72     uint32_t regVal;
74     /* Setting the GPIO direction to output */
75     regVal = HW_RD_REG32(CSL_GPIO0_BASE + 0x10);
76     regVal &= ~(0x01 << (BOARD_SDIO_1V8_EN_PIN_NUM % 32));
77     HW_WR_REG32((CSL_GPIO0_BASE + 0x10), regVal);
79     /* Setting the GPIO value */
80     regVal = HW_RD_REG32(CSL_GPIO0_BASE + 0x18);
82     if(gpioValue == 0)
83     {
84         regVal &= ~(0x01 << (BOARD_SDIO_1V8_EN_PIN_NUM % 32));
85         HW_WR_REG32((CSL_GPIO0_BASE + 0x18), regVal);
86     }
87     else
88     {
89         regVal |= (gpioValue << (BOARD_SDIO_1V8_EN_PIN_NUM % 32));
90         HW_WR_REG32((CSL_GPIO0_BASE + 0x18), regVal);
91     }
92 }
94 /**
95  * \brief Board ID read function
96  *
97  * \param   info     [IN]  Board info structure
98  * \param   boardID  [IN]  ID of the board to be detected
99  * \n                      BOARD_ID_GESI(0x0) - GESI Board
100  * \n                      BOARD_ID_FUSION2(0x1) - Fusion 2 Board
101  * \n                      BOARD_ID_ENET(0x2) - ENET Board
102  * \n                      BOARD_ID_EVM(0x3) - EVM Board
103  *
104  * \return   BOARD_SOK in case of success or appropriate error code.
105  *
106  */
107 Board_STATUS Board_getBoardData(Board_IDInfo_v2 *info, uint32_t boardID)
109     Board_I2cInitCfg_t i2cCfg = {0};
110     Board_STATUS status;
112     i2cCfg.i2cInst    = gBoardDetCfg[boardID].i2cInst;
113     i2cCfg.socDomain  = gBoardDetCfg[boardID].socDomain;
114     i2cCfg.enableIntr = false;
115     Board_setI2cInitConfig(&i2cCfg);
117     status = Board_getIDInfo_v2(info, gBoardDetCfg[boardID].slaveAddr);
119     return status;
122 /**
123  * \brief Board detect function
124  *
125  *  Checks if the board with given 'boardID' is connected to the
126  *  base board.
127  *
128  *  \n Note: Board ID EEPROM should be programmed for this function
129  *           to work properly.
130  *
131  * \param   boardID  [IN]  ID of the board to be detected
132  * \n                      BOARD_ID_GESI(0x0) - GESI Board
133  * \n                      BOARD_ID_FUSION2(0x1) - Fusion 2 Board
134  * \n                      BOARD_ID_ENET(0x2) - ENET Board
135  * \n                      BOARD_ID_EVM(0x3) - EVM Board
136  *
137  * \return   TRUE if the given board is detected else FALSE.
138  *           SoM board will be always connected to the base board.
139  *           For SoM boardID return value TRUE indicates dual PMIC
140  *           SoM and FALSE indicates alternate PMIC SoM
141  *
142  */
143 bool Board_detectBoard(uint32_t boardID)
145     Board_IDInfo_v2 info = {0};
146     Board_STATUS status;
147     bool bDet = FALSE;
149     if(boardID <= BOARD_ID_EVM)
150     {
151         status = Board_getBoardData(&info, boardID);
152         if(status == 0)
153         {
154             if(!(strncmp(info.boardInfo.boardName,
155                          gBoardDetCfg[boardID].bName,
156                          BOARD_BOARD_NAME_LEN)))
157             {
158                 bDet = TRUE;
159             }
160         }
161     }
163     return bDet;
166 /**
167  * \brief  Checks for Alpha board revision
168  *
169  * \param   boardID  [IN]  ID of the board to be detected
170  * \n                      BOARD_ID_GESI(0x0) - GESI Board
171  * \n                      BOARD_ID_FUSION2(0x1) - Fusion 2 Board
172  * \n                      BOARD_ID_ENET(0x2) - ENET Board
173  * \n                      BOARD_ID_EVM(0x3) - EVM Board
174  *
175  * \return TRUE if board revision is Alpha, FALSE for all other cases
176  */
177 bool Board_isAlpha(uint32_t boardID)
179     bool alphaBoard = FALSE;
181     return alphaBoard;
184 /**
185  *  \brief    Function to detect ENET expansion application card type
186  *
187  *  ENET expansion connector supports QSGMII and SGMII application cards.
188  *  This function detects type of the application card connected on
189  *  ENET expansion connector.
190  *
191  *  \return
192  *            0 (BOARD_ENET_NONE)   - No board connected or invalid board ID data
193  *            1 (BOARD_ENET_QSGMII) - QSGMII board connected
194  *            2 (BOARD_ENET_SGMII)  - SGMII board connected
195  *           -1 (BOARD_ENET_UNKOWN) - Unknown board
196 */
197 int32_t Board_detectEnetCard(void)
199     Board_IDInfo_v2 info = {0};
200     Board_STATUS status;
201     int8_t ret = 0;
203     status = Board_getBoardData(&info, BOARD_ID_ENET);
204     if(status == 0)
205     {
206         if((strcmp(info.boardInfo.boardName, "J7X-VSC8514-ETH")) == 0)
207         {
208             ret = BOARD_ENET_QSGMII;
209         }
210         else if((strcmp(info.boardInfo.boardName, "J7X-DP83869-ETH")) == 0)
211         {
212             ret = BOARD_ENET_SGMII;
213         }
214         else
215         {
216             ret = BOARD_ENET_UNKOWN;
217         }
218     }
219     else
220     {
221         ret = BOARD_ENET_NONE;
222     }
224     return ret;
227 /**
228  * \brief Read MAC ID function
229  *
230  *  This function reads the MAC addresses programmed to the board ID EEPROM
231  *  on the boards with Ethernet ports. Exception is for MCU Ethernet port
232  *  which is supposed to use MAC ID from SoC MMR registers.
233  *
234  *  There can be multiple MAC IDs stored in the EEPROM based on the
235  *  number of Ethernet ports on the board. Number of MAC IDs copied
236  *  to 'macAddrBuf' can be read using 'macAddrCnt' parameters.
237  *
238  *  Each MAC address will be 6 bytes long. MAC IDs will be copied to buffer
239  *  based on 'macBufSize'. If the buffer size is long enough, all the MAC
240  *  addresses from EEPROM will be copied to 'macAddrBuf' else fewer MAC
241  *  IDs to fit within 'macBufSize'. MAC count for a given board can be
242  *  read using Board_readMacAddrCount() function.
243  *
244  *  \n Note: Board ID EEPROM should be programmed for this function
245  *           to work properly.
246  *
247  * \param  boardID  [IN]  ID of the board to be detected
248  * \n                      BOARD_ID_GESI(0x0) - GESI Board
249  * \n                      BOARD_ID_FUSION2(0x1) - Fusion 2 Board
250  * \n                      BOARD_ID_ENET(0x2) - ENET Board
251  * \n                      BOARD_ID_EVM(0x3) - EVM Board
252  * \param  macAddrBuf[OUT] Buffer to write MAC IDs read from EEPROM
253  * \param  macBufSize[IN]  Size of the macAddrBuf
254  * \param  macAddrCnt[OUT] Number of valid MAC addresses programmed to the EEPROM
255  *                         This an optional variable to read the MAC ID count
256  *                         filled to the 'macAddrBuf'.
257  *                         Pass a valid address to get MAC ID count.
258  *
259  * \return   BOARD_SOK in case of success or appropriate error code.
260  *
261  */
262 Board_STATUS Board_readMacAddr(uint32_t boardID,
263                                uint8_t  *macAddrBuf,
264                                uint32_t macBufSize,
265                                uint32_t *macAddrCnt)
267     Board_IDInfo_v2 info = {0};
268     Board_STATUS status;
269     uint8_t macCount = 0;
271     if((boardID <= BOARD_ID_EVM) && (macAddrBuf != NULL))
272     {
273         status = Board_getBoardData(&info, boardID);
274         if(status == 0)
275         {
276             macCount = ((info.macInfo.macControl & BOARD_MAC_COUNT_MASK)
277                           >> BOARD_MAC_COUNT_SHIFT) + 1;
278             if(macBufSize < (macCount * BOARD_MAC_ADDR_BYTES))
279             {
280                 macCount = (macBufSize / BOARD_MAC_ADDR_BYTES);
281             }
283             memcpy(macAddrBuf, &(info.macInfo.macAddress[0]),
284                    (macCount * BOARD_MAC_ADDR_BYTES));
285         }
286     }
287     else
288     {
289         status = BOARD_INVALID_PARAM;
290     }
292     if(macAddrCnt != NULL)
293     {
294         *macAddrCnt = macCount;
295     }
297     return status;
300 /**
301  * \brief Read MAC ID count
302  *
303  *  This function reads the number of MAC addresses programmed to
304  *  board ID EEPROM on the boards with Ethernet ports. Exception is
305  *  for MCU Ethernet port which is supposed to use MAC ID from SoC
306  *  MMR registers. Each MAC address programmed to EEPROM is 6 bytes long.
307  *
308  *  \n Note: Board ID EEPROM should be programmed for this function
309  *           to work properly.
310  *
311  * \param  boardID  [IN]  ID of the board to be detected
312  * \n                      BOARD_ID_GESI(0x0) - GESI Board
313  * \n                      BOARD_ID_FUSION2(0x1) - Fusion 2 Board
314  * \n                      BOARD_ID_ENET(0x2) - ENET Board
315  * \n                      BOARD_ID_EVM(0x3) - EVM Board
316  * \param  macAddrCnt[OUT] Number of valid MAC addresses programmed to the EEPROM
317  *
318  * \return   BOARD_SOK in case of success or appropriate error code.
319  *
320  */
321 Board_STATUS Board_readMacAddrCount(uint32_t boardID,
322                                     uint32_t *macAddrCnt)
324     Board_IDInfo_v2 info = {0};
325     Board_STATUS status;
327     if((boardID <= BOARD_ID_EVM) && (macAddrCnt != NULL))
328     {
329         status = Board_getBoardData(&info, boardID);
330         if(status == 0)
331         {
332             *macAddrCnt = ((info.macInfo.macControl & BOARD_MAC_COUNT_MASK)
333                            >> BOARD_MAC_COUNT_SHIFT) + 1;
334         }
335     }
336     else
337     {
338         status = BOARD_INVALID_PARAM;
339     }
341     return status;
344 /**
345  * \brief Function to configure I2C configurations used by board
346  *
347  * This function is used to set the I2C controller instance and
348  * SoC domain used by the board module for IO expander and board
349  * ID info read.
350  *
351  * Usage:
352  * Call Board_setI2cInitConfig to set the I2C configurations
353  * Call IO expander Init or Board ID info read/write
354  *
355  *  \return   BOARD_SOK in case of success or appropriate error code.
356  *
357  */
358 Board_STATUS Board_setI2cInitConfig(Board_I2cInitCfg_t *i2cCfg)
360     if(i2cCfg == NULL)
361     {
362         return BOARD_INVALID_PARAM;
363     }
365     gBoardI2cInitCfg = *i2cCfg;
367     return BOARD_SOK;
370 /**
371  * \brief Function to get board init params
372  *
373  *  This function shall be used to know the current board init
374  *  parameters and update them if needed using the function Board_setInitParams.
375  *
376  * \param   initParams  [IN]  Board init params structure
377  *
378  * \return   BOARD_SOK in case of success or appropriate error code.
379  *
380  */
381 Board_STATUS Board_getInitParams(Board_initParams_t *initParams)
383     if(initParams == NULL)
384     {
385         return BOARD_INVALID_PARAM;
386     }
388     *initParams = gBoardInitParams;
390     return BOARD_SOK;
393 /**
394  * \brief Function to configure board init parameters
395  *
396  *  Board init params includes the parameters used by Board_init
397  *  function for different operations. Default init parameters
398  *  used by Board_init can be updated using this function.
399  *  All the default params can be overwritten by calling this function
400  *  or some of can be changed by reading the existing init parameters
401  *  using Board_getInitParams function.
402  *
403  * Usage:
404  * Call Board_getInitParams to get the default board init parameters
405  * Update the parameters as needed
406  * Call Board_setInitParams to update the default board init parameters
407  *
408  * \param   initCfg  [IN]  Board Init config structure
409  *
410  * \return   BOARD_SOK in case of success or appropriate error code.
411  *
412  */
413 Board_STATUS Board_setInitParams(Board_initParams_t *initParams)
415     if(initParams == NULL)
416     {
417         return BOARD_INVALID_PARAM;
418     }
420     gBoardInitParams = *initParams;
422     return BOARD_SOK;
425 /**
426  * \brief Voltage Switching function for MMCSD
427  *
428  * Functionality: Change the voltage of the MMC CMD & DAT lines.
429  *  This function is called by the MMCSD card driver (if the driver is
430  *  configured to use this function at init time by the application) to change
431  *  the CMD & DAT voltage from 3.0V to 1.8V if a UHS-I card is found.
432  *  This function configures the PMIC controller of the board to switch the voltage
433  *
434  *  Note: This function uses non-standard board API naming and return type
435  *        to align with existing platforms.
436  *
437  * \param   instance       [IN]  Device instance
438  * \param   switchVoltage  [IN]  MMCSD IO voltage value
439  *
440  */
441 MMCSD_Error Board_mmc_voltageSwitchFxn(uint32_t instance,
442                                        MMCSD_BusVoltage_e switchVoltage)
444         MMCSD_Error mmcRetVal = MMCSD_OK;
446     if(switchVoltage == MMCSD_BUS_VOLTAGE_1_8V)
447     {
448        Board_sdVoltageCtrlGpioCfg(0);
449     }
450     else if(switchVoltage == MMCSD_BUS_VOLTAGE_3_3V)
451     {
452        Board_sdVoltageCtrlGpioCfg(1);
453         }
454     else
455     {
456         mmcRetVal = MMCSD_ERR;
457     }
459         return(mmcRetVal);
462 /**
463  * \brief Function to get the SoC domain
464  *
465  *  This function returns the domain of the SoC core on which
466  *  it is executing.
467  *
468  * \return   SoC domain of the core.
469  *
470  */
471 uint32_t Board_getSocDomain(void)
473     uint32_t socDomain = BOARD_SOC_DOMAIN_MAIN;
475 #ifdef BUILD_MCU
476     CSL_ArmR5CPUInfo info;
478     CSL_armR5GetCpuID(&info);
479     if (info.grpId == (uint32_t)CSL_ARM_R5_CLUSTER_GROUP_ID_0)
480     {
481         socDomain = BOARD_SOC_DOMAIN_MCU;
482     }
483 #endif
485   return socDomain;
488 /**
489  *  \brief  Sets RAT configuration
490  *
491  *  MAIN padconfig registers are not directly accessible for C66x core
492  *  which requires RAT configuration for the access.
493  *
494  *  \return   None
495  */
496 void Board_setRATCfg(void)
498     /* Not used. Place holder for any future updates */
501 /**
502  *  \brief  Restores RAT configuration
503  *
504  *  \return   None
505  */
506 void Board_restoreRATCfg(void)
508     /* Not used. Place holder for any future updates */
511 /**
512  *  \brief    Function to generate delay in micro seconds
513  *
514  *  This function takes the delay parameters in usecs but the generated
515  *  delay will be in multiples of msecs due to the osal function which
516  *  generates delay in msecs. Delay parameter passed will be converted to
517  *  msecs and fractional value will be adjusted to nearest msecs value.
518  *  Minimum delay generated by this function is 1 msec.
519  *  Function parameter is kept in usecs to match with existing
520  *  platforms which has delay function for usecs.
521  *
522  *  \param    usecs [IN]  Specifies the time to delay in micro seconds.
523  *
524  */
525 void BOARD_delay(uint32_t usecs)
527     uint32_t msecs;
529     msecs = usecs/1000;
530     if(usecs%1000)
531     {
532         msecs += 1;
533     }
535     Osal_delay(msecs);