]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/hw/serdes/serdes.c
Merge pull request #3 in PROCESSOR-SDK/ibl from PRSDK-5675 to master
[keystone-rtos/ibl.git] / src / hw / serdes / serdes.c
1 /***********************************************************************************
2  * FILE PURPOSE: Serdes configuration
3  ***********************************************************************************
4  * FILE NAME: serdes.c
5  *
6  * DESCRIPTION: Performs serdes configurations
7  *
8  ***********************************************************************************/
9 #include "types.h"
10 #include "serdes_api.h"
11 #include "serdesloc.h"
12 #include "device.h"
15 /************************************************************************************
16  * FUNCTION PURPOSE: Enable and configure serdes
17  ************************************************************************************
18  * DESCRIPTION: The serdes is configured and enabled
19  ************************************************************************************/
20 SINT16 hwSerdesConfig (UINT32 sBase, serdesConfig_t *scfg)
21 {
22     UINT32 reg;
23     UINT32 regb;
24     SINT32 i;
27     /* If the serdes is already enabled and the new value does not match
28      * the current value, the serdes is first disabled. Dont compare 
29      * the sleep value in the register, which can be toggled dynamically */
30     reg  = DEVICE_REG32_R (sBase + SERDES_REG_CFG);
31     reg  = SERDES_SET_CFG_SLEEP(reg, 0);
32     regb = SERDES_SET_CFG_SLEEP(scfg->cfg, 0);
34     chipKickOpenSerdes(sBase);
36     if ( (SERDES_GET_ENABLE(reg) == 1)         && 
37          (SERDES_GET_ENABLE(scfg->cfg) == 1)   &&
38          (reg != regb)                           )   {
40         reg = SERDES_SET_ENABLE(reg, 0);
41         DEVICE_REG32_W (sBase + SERDES_REG_CFG, reg);
42         chipDelay32 (100);
43     }
46     /* Config register. After enable it takes upt to 350ns, or 200 cycles to 
47      * stabalize. Although these are serdes clock cycles the delay here is
48      * in cpu cycles. The PLL status will be checked by the peripheral
49      * using the PLL */
52     DEVICE_REG32_W (sBase + SERDES_REG_CFG, regb);
53     chipDelay32 (200);
55     /* Some devices have unreliable lock status bits. Add an extra delay
56      * to allow the serdes to lock */
57     chipDelay32 (TARGET_SERDES_LOCK_DELAY);
60     /* rx and tx config registers */
61     for (i = 0; i < scfg->nLanes; i++)  {
63         DEVICE_REG32_W (sBase + SERDES_REG_RX(i), scfg->rxCfg[i]);
64         DEVICE_REG32_W (sBase + SERDES_REG_TX(i), scfg->txCfg[i]);
66     }
68     chipKickClosedSerdes(sBase);
70     return (0);
72 } /* hwSerdesConfig */
76 /*******************************************************************************************
77  * FUNCTION PURPOSE: Wait for a serdes lock on lane 0
78  *******************************************************************************************
79  * DESCRIPTION: Waits for a lock on lane 0. Doesn't trap if the lock is not found
80  *******************************************************************************************/
81 SINT16 hwSerdesWaitLock (UINT32 statusBase)
82 {
83     UINT32 reg;
84     UINT32 i;
86     for (i = 0; i < 100; i++)  {
87         reg = DEVICE_REG32_R (statusBase);
88         if (reg & 1)
89             return (0);
91         chipDelay32 (1000);
92     }
94     return (-1);
96 } /* hwSerdesWaitLock */