Merge pull request #3 in PROCESSOR-SDK/ibl from PRSDK-5675 to master
[keystone-rtos/ibl.git] / src / device / c665x / c665x.c
1 /*
2  *
3  * Copyright (C) 2011-12 Texas Instruments Incorporated - http://www.ti.com/ 
4  * 
5  * 
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions 
8  *  are met:
9  *
10  *    Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  *    Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the   
16  *    distribution.
17  *
18  *    Neither the name of Texas Instruments Incorporated nor the names of
19  *    its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
26  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
27  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34 */
38 /************************************************************************************
39  * FILE PURPOSE: C66x Device Specific functions
40  ************************************************************************************
41  * FILE NAME: c66x.c
42  *
43  * DESCRIPTION: Implements the device specific functions for the IBL
44  *
45  * @file c66x.c
46  *
47  * @brief
48  *  This file implements the device specific functions for the IBL
49  *
50  ************************************************************************************/
51 #include "ibl.h"
52 #include "iblloc.h"
53 #include "iblcfg.h"
54 #include "device.h"
55 #include "pllapi.h"
56 #include "emif31api.h"
57 #include "pscapi.h"
58 #include "gpio.h"
59 #include "qm_api.h"
60 #include "cpdma_api.h"
61 #include "pa_api.h"
62 #include "serdes_api.h"
63 #include "net.h"
64 #include "nandhwapi.h"
65 #include "nor_api.h"
66 #include "spi_api.h"
67 #include <string.h>
68 #include <stdint.h>
69 #include "target.h"
70 #include "uart.h"
72 #define PLL_DDR_INIT_LOOPMAX 10
73 #define IBL_RESULT_CODE_STR_LEN 20
74 #define IBL_RESULT_CODE_LOC 17
76 extern cregister unsigned int DNUM;
78 /**
79  *  @brief Determine if an address is local
80  *
81  *  @details
82  *    Examines an input address to determine if it is a local address. Using the largest
83  *    L2 size on the C6657.
84  */
85 bool address_is_local (Uint32 addr)
86 {
87     /* L2 */
88     if ((addr >= 0x00800000) && (addr < 0x00900000))
89         return (TRUE);
91     /* L1P */
92     if ((addr >= 0x00e00000) && (addr < 0x00e08000))
93         return (TRUE);
95     /* L2D */
96     if ((addr >= 0x00f00000) && (addr < 0x00f08000))
97         return (TRUE);
99     return (FALSE);
104 /**
105  * @brief  Convert a local l1d, l1p or l2 address to a global address
106  *
107  * @details
108  *  The global address is formed. If the address is not local then
109  *  the input address is returned
110  */
111 Uint32 deviceLocalAddrToGlobal (Uint32 addr)
114     if (address_is_local (addr))
115         addr = (1 << 28) | (DNUM << 24) | addr;
117     return (addr);
120         
121         
122 /**
123  * @brief
124  *   Enable the DDR
125  *
126  * @details
127  *   The DDR controller on the c66x is an emif 4.0. The controller is
128  *   initialized directly with the supplied values
129  */
130 void deviceDdrConfig (void)
132     uint32 loopcount=0;
133     int8  ddr_result_code_str[IBL_RESULT_CODE_STR_LEN] = "IBL Result code 0";
134     /* The emif registers must be made visible. MPAX mapping 2 is used */
135     DEVICE_REG_XMPAX_L(2) =  0x10000000 | 0xff;     /* replacement addr + perm*/
136     DEVICE_REG_XMPAX_H(2) =  0x2100000B;         /* base addr + seg size (64KB)*/       
137     
138     if (ibl.ddrConfig.configDdr != 0)
139         hwEmif4p0Enable (&ibl.ddrConfig.uEmif.emif4p0);
142         
145 /**
146  *  @brief  Enable EMIF25 or SPI interface to the NAND
147  *
148  */
149 int32 deviceConfigureForNand(void)
152     return (0);
156 /**
157  *  @brief
158  *      Return the base memory address for emif25 in a given chip select space
159  */
160 uint32 deviceEmif25MemBase (int32 cs)
162     switch (cs)  {
164         case 2:  return (TARGET_MEM_NAND_CS_2);
166         case 3:  return (TARGET_MEM_NAND_CS_3);
168         case 4:  return (TARGET_MEM_NAND_CS_4);
170         case 5:  return (TARGET_MEM_NAND_CS_5);
172     }
174     return (0xffffffff);
179 /**
180  *  @brief
181  *      Return the PSC number for NAND/NOR through emif. 
182  */
183 Int32 deviceEmifPscNum (void)
185     Uint32 v;
187     v = *((Uint32 *)DEVICE_JTAG_ID_REG);
188     v &= DEVICE_JTAG_ID_MASK;
189     if (v == DEVICE_C6657_JTAG_ID_VAL)
190         return (TARGET_PWR_EMIF_C6657);
192     /* Return a negative number to indicate no PSC module is associated with NAND */
193     return (-1);
199 /**
200  *  @brief
201  *    The e-fuse mac address is loaded
202  */
203 void deviceLoadDefaultEthAddress (uint8 *maddr)
205     uint32 macA, macB;
207     /* Read the e-fuse mac address */
208     macA = *((uint32 *)0x2620110);
209     macB = *((uint32 *)0x2620114);
211     maddr[0] = (macB >>  8) & 0xff;
212     maddr[1] = (macB >>  0) & 0xff;
213     maddr[2] = (macA >> 24) & 0xff;
214     maddr[3] = (macA >> 16) & 0xff;
215     maddr[4] = (macA >>  8) & 0xff;
216     maddr[5] = (macA >>  0) & 0xff;
219 extern nandCtbl_t nandEmifCtbl;
220 /**
221  *  @brief Return the NAND interface (GPIO, EMIF25 or SPI) used based on the value
222  *         of interface
223  */
224 #ifndef EXCLUDE_NAND_GPIO
225 nandCtbl_t nandGpioCtbl =  {
227     nandHwGpioDriverInit,
228     nandHwGpioDriverReadBytes,
229     nandHwGpioDriverReadPage,
230     nandHwGpioDriverClose
232 };
233 #endif
235 #ifndef EXCLUDE_NAND_EMIF
236 extern Int32 nandHwEmifDriverInit (int32 cs, void *vdevInfo);
237 extern Int32 nandHwEmifDriverReadBytes (Uint32 block, Uint32 page, Uint32 byte, Uint32 nbytes, Uint8 *data);
238 extern Int32 nandHwEmifDriverReadPage (Uint32 block, Uint32 page, Uint8 *data);
239 extern Int32 nandHwEmifDriverClose (void);
241 nandCtbl_t nandEmifCtbl =  {
243     nandHwEmifDriverInit,
244     nandHwEmifDriverReadBytes,
245     nandHwEmifDriverReadPage,
246     nandHwEmifDriverClose
248 };
249 #endif
251 #ifndef EXCLUDE_NAND_SPI
252 nandCtbl_t nandSpiCtbl =  {
255     nandHwSpiDriverInit,
256     nandHwSpiDriverReadBytes,
257     nandHwSpiDriverReadPage,
258     nandHwSpiDriverClose
260 };
261 #endif
263 nandCtbl_t *deviceGetNandCtbl (int32 interface)
265 #ifndef EXCLUDE_NAND_GPIO
267     if (interface == ibl_PMEM_IF_GPIO)
268         return (&nandGpioCtbl);
270 #endif
272 #ifndef EXCLUDE_NAND_SPI
274     if (interface == ibl_PMEM_IF_SPI)
275         return (&nandSpiCtbl);
277 #endif
279 #ifndef EXCLUDE_NAND_EMIF
281     if ((interface >= ibl_PMEM_IF_CHIPSEL_2) && (interface <= ibl_PMEM_IF_CHIPSEL_5))
282         return (&nandEmifCtbl);
284 #endif
286     return (NULL);
291 /**
292  * @brief
293  *      Get the nor call table for the specified nor interface
294  */
296 #ifndef EXCLUDE_NOR_EMIF
297 norCtbl_t norEmifCtbl = {
298     
299     norHwEmifDriverInit,
300     norHwEmifDriverReadBytes,
301     norHwEmifDriverClose
303 };
305 #endif
307 #ifndef EXCLUDE_NOR_SPI
309 norCtbl_t norSpiCtbl = {
310     
311     norHwSpiDriverInit,
312     norHwSpiDriverReadBytes,
313     norHwSpiDriverClose
315 };
317 #endif
319 norCtbl_t *deviceGetNorCtbl (int32 interface)
322 #ifndef EXCLUDE_NOR_SPI
323     
324     if (interface == ibl_PMEM_IF_SPI)
325         return (&norSpiCtbl);
327 #endif
329 #ifndef EXCLUDE_NOR_EMIF
330    
331     if ((interface >= ibl_PMEM_IF_CHIPSEL_2) && (interface <= ibl_PMEM_IF_CHIPSEL_5))
332         return (&norEmifCtbl);
334 #endif
336     return (NULL);
340 /**
341  *  @brief
342  *      Chip level SGMII serdes configuration
343  *
344  *  @details
345  *      Both lanes are always setup, regardless of the port value
346  */
347 void targetSgmiiSerdesConfig (int32 port, void *viblSgmii)
349   serdesConfig_t scfg;
350   iblSgmii_t     *sgmii = (iblSgmii_t *)viblSgmii;
352   scfg.cfg      = sgmii->auxConfig;
353   scfg.nLanes   = 2;
354   scfg.rxCfg[0] = scfg.rxCfg[1] = sgmii->rxConfig;
355   scfg.txCfg[0] = scfg.txCfg[1] = sgmii->txConfig;
357   hwSerdesConfig (TARGET_SGMII_SERDES_BASE, &scfg);
359   hwSerdesWaitLock (TARGET_SGMII_SERDES_STATUS_BASE);
362     
365     
371