update mcsdk_tools based on platform library 00.03
[keystone-rtos/mcsdk-tools.git] / post / src / c6678.c
1 /*
2  *
3  * Copyright (C) 2010 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: C6678 Device Specific functions
40  ************************************************************************************
41  * FILE NAME: c6678.c
42  *
43  * DESCRIPTION: Implements the device specific functions for the IBL
44  *
45  * @file c6678.c
46  *
47  * @brief
48  *  This file implements the device specific functions for the IBL
49  *
50  ************************************************************************************/
51 #include <string.h>
52 #include "platform.h"
53 #include "qm_api.h"
54 #include "cpdma_api.h"
55 #include "pa_api.h"
56 #include "net.h"
57 #include "target.h"
59 extern cregister unsigned int DNUM;
61 /***********************************************************************************
62  * FUNCTION PURPOSE: Provide an approximate delay
63  ***********************************************************************************
64  * DESCRIPTION: A delay in units of CPU cycles is executed
65  ***********************************************************************************/
66 void chipDelay32 (uint32_t del)
67 {
68     volatile unsigned int i;
70     for (i = 0; i < del/8; i++);
72 }
74 void *iblMemcpy (void *s1, const void *s2, uint32_t n)
75 {
76     return (memcpy (s1, s2, n));
78 }
80 /**
81  *  @brief Determine if an address is local
82  *
83  *  @details
84  *    Examines an input address to determine if it is a local address. Using the largest
85  *    L2 size on the 6616.
86  */
87 bool address_is_local (uint32_t addr)
88 {
89     /* L2 */
90     if ((addr >= 0x00800000) && (addr < 0x00900000))
91         return (TRUE);
93     /* L1P */
94     if ((addr >= 0x00e00000) && (addr < 0x00e08000))
95         return (TRUE);
97     /* L2D */
98     if ((addr >= 0x00f00000) && (addr < 0x00f08000))
99         return (TRUE);
101     return (FALSE);
106 /**
107  * @brief  Convert a local l1d, l1p or l2 address to a global address
108  *
109  * @details
110  *  The global address is formed. If the address is not local then
111  *  the input address is returned
112  */
113 uint32_t deviceLocalAddrToGlobal (uint32_t addr)
116     if (address_is_local (addr))
117         addr = (1 << 28) | (DNUM << 24) | addr;
119     return (addr);
125 /**
126  *  @brief
127  *    The e-fuse mac address is loaded
128  */
129 void deviceLoadDefaultEthAddress (uint8_t *maddr)
131     uint32_t macA, macB;
133     /* Read the e-fuse mac address */
134     macA = *((uint32_t *)0x2620110);
135     macB = *((uint32_t *)0x2620114);
137     maddr[0] = (macB >>  8) & 0xff;
138     maddr[1] = (macB >>  0) & 0xff;
139     maddr[2] = (macA >> 24) & 0xff;
140     maddr[3] = (macA >> 16) & 0xff;
141     maddr[4] = (macA >>  8) & 0xff;
142     maddr[5] = (macA >>  0) & 0xff;
146 /**
147  *  @brief
148  *    Compile time queue manager information
149  */
150 #define DEVICE_NUM_RX_CPPIS     1
151 #define DEVICE_NUM_TX_CPPIS     1
152 #define DEVICE_NUM_CPPIS        (DEVICE_NUM_RX_CPPIS + DEVICE_NUM_TX_CPPIS)
154 /* The linking RAM */
155 #pragma DATA_SECTION(qm_linkram_buf, ".linkram")
156 #pragma DATA_ALIGN(qm_linkram_buf, 16)
157 uint8_t qm_linkram_buf[DEVICE_NUM_CPPIS * 2 * (sizeof(uint32_t)/sizeof(uint8_t))];
160 /* The CPPI RAM */
161 #pragma DATA_SECTION(qm_cppi_buf, ".cppi")
162 #pragma DATA_ALIGN(qm_cppi_buf, 16)
163 uint8_t qm_cppi_buf[QM_DESC_SIZE_BYTES * DEVICE_NUM_CPPIS];
165 /* The rx data buffers */
166 #pragma DATA_SECTION(qm_buffer, ".mac_buffer")
167 #pragma DATA_ALIGN(qm_buffer, 16)
168 uint8_t qm_buffer[MAX_SIZE_STREAM_BUFFER * DEVICE_NUM_RX_CPPIS];
170 const qmConfig_t qmConfig =  {
171     (uint32_t) qm_linkram_buf,
172     sizeof  (qm_cppi_buf),
173     (uint32_t) qm_cppi_buf,
175     DEVICE_NUM_CPPIS,
176     DEVICE_QM_FREE_Q
177 };
179 /**
180  *  @brief
181  *      Return the queue manager memory configuration information
182  */
183 void *targetGetQmConfig (void)
185     return ((void *)&qmConfig);
188 /**
189  *  @brief
190  *      Attach a packet buffer to each descriptor and push onto the linked buffer queue
191  */
192 void targetInitQs (void)
194     int32_t i;
195     qmHostDesc_t *hd, *hd_old;
197     for (i = 0; i < DEVICE_NUM_RX_CPPIS; i++)  {
199         hd                = hwQmQueuePop (DEVICE_QM_FREE_Q);
200         hd_old            = hd;
201         hd->buffLen       = sizeof (qm_buffer) / DEVICE_NUM_CPPIS;
202         hd->buffPtr       = (uint32_t) &(qm_buffer[MAX_SIZE_STREAM_BUFFER * i]);
203         hd->nextBDPtr     = 0;
204         hd->origBufferLen = MAX_SIZE_STREAM_BUFFER;
205         hd->origBuffPtr   = hd->buffPtr;
207         hwQmQueuePush (hd, DEVICE_QM_LNK_BUF_Q, QM_DESC_SIZE_BYTES);
209     }
212     for (i = 0; i < DEVICE_NUM_TX_CPPIS; i++)  {
214         hd                = hwQmQueuePop (DEVICE_QM_FREE_Q);
215         if (hd == hd_old)
216                 hd += 0x40;
217         hd->buffLen       = 0;
218         hd->buffPtr       = 0;
219         hd->nextBDPtr     = 0;
220         hd->origBufferLen = 0;
221         hd->origBuffPtr   = 0;
223         hwQmQueuePush (hd, DEVICE_QM_TX_Q, QM_DESC_SIZE_BYTES);
225     }
232 const cpdmaRxCfg_t cpdmaEthRxCfg =  {
234     DEVICE_PA_CDMA_RX_CHAN_CFG_BASE,    /* Base address of PA CPDMA rx config registers */
235     DEVICE_PA_CDMA_RX_NUM_CHANNELS,     /* Number of rx channels */
237     DEVICE_PA_CDMA_RX_FLOW_CFG_BASE,    /* Base address of PA CPDMA rx flow registers */
238     DEVICE_PA_CDMA_RX_NUM_FLOWS,        /* Number of rx flows */
240     0,                                  /* Queue manager for descriptor / buffer for received packets */
241     DEVICE_QM_LNK_BUF_Q,                /* Queue of descriptors /buffers for received packets */
243     0,                                  /* Queue manager for received packets */
244     DEVICE_QM_RCV_Q,                    /* Queue for received packets (overridden by PA)  */
246     DEVICE_RX_CDMA_TIMEOUT_COUNT        /* Teardown maximum loop wait */
247 };
250 /**
251  *  @brief
252  *      Return the cpdma configuration information
253  */
254 void *targetGetCpdmaRxConfig (void)
256     return ((void *)&cpdmaEthRxCfg);
261 const cpdmaTxCfg_t cpdmaEthTxCfg = {
263     DEVICE_PA_CDMA_GLOBAL_CFG_BASE,     /* Base address of global config registers      */
264     DEVICE_PA_CDMA_TX_CHAN_CFG_BASE,    /* Base address of PA CPDMA tx config registers */
265     DEVICE_PA_CDMA_TX_NUM_CHANNELS      /* Number of tx channels */
267 };
270 /**
271  *  @brief
272  *      return the tx cpdma configuration information
273  */
274 void *targetGetCpdmaTxConfig (void)
276     return ((void *)&cpdmaEthTxCfg);
280 /**
281  *  @brief
282  *     Configure the PA
283  */
284 void targetPaConfig (uint8_t *macAddr)
286     paConfig_t     paCfg;
287     qmHostDesc_t  *hd;
288     int16_t         ret;
290     /* Filter everything except the desired mac address and the broadcast mac */
291     paCfg.mac0ms = ((uint32_t)macAddr[0] << 24) | ((uint32_t)macAddr[1] << 16) | ((uint32_t)macAddr[2] << 8) | (uint32_t)(macAddr[3]);
292     paCfg.mac0ls = ((uint32_t)macAddr[4] << 24) | ((uint32_t)macAddr[5] << 16);
294     paCfg.mac1ms = 0xffffffff;
295     paCfg.mac1ls = 0xffff0000;
297     paCfg.rxQnum = DEVICE_QM_RCV_Q;
299     /* Form the configuration command in a buffer linked to a descriptor */
300     hd = hwQmQueuePop (DEVICE_QM_LNK_BUF_Q);
301     paCfg.cmdBuf = (uint8_t *)hd->origBuffPtr;
303     ret = hwPaEnable (&paCfg);
304     if (ret != 0)  {
305         return;
306     }
309     /* Send the command to the PA through the QM */
310     hd->softwareInfo0 = PA_MAGIC_ID;
311     hd->buffLen = 16;
312     QM_DESC_DESCINFO_SET_PKT_LEN(hd->descInfo, 16);
314     /* Set the return Queue */
315     QM_DESC_PINFO_SET_QM    (hd->packetInfo, 0);
316     QM_DESC_PINFO_SET_QUEUE (hd->packetInfo, DEVICE_QM_LNK_BUF_Q);
318     hwQmQueuePush (hd, DEVICE_QM_PA_CFG_Q, QM_DESC_SIZE_BYTES);
323 int32_t targetMacSend (void *vptr_device, uint8_t* buffer, int32_t num_bytes)
325     qmHostDesc_t   *hd;
326     int32_t        i;
329     /* Must always setup the descriptor to have the minimum packet length */
330     if (num_bytes < 64)
331         num_bytes = 64;
334     for (i = 0, hd = NULL; hd == NULL; i++, chipDelay32 (1000))
335         hd = hwQmQueuePop (DEVICE_QM_TX_Q);
337     if (hd == NULL)
338         return (-1);
340     QM_DESC_DESCINFO_SET_PKT_LEN(hd->descInfo, num_bytes);
342     hd->buffLen       = num_bytes;
343     hd->origBufferLen = num_bytes;
345     hd->buffPtr     = deviceLocalAddrToGlobal((uint32_t)buffer);
346     hd->origBuffPtr = deviceLocalAddrToGlobal((uint32_t)buffer);
349     /* Return the descriptor back to the transmit queue */
350     QM_DESC_PINFO_SET_QM(hd->packetInfo, 0);
351     QM_DESC_PINFO_SET_QUEUE(hd->packetInfo, DEVICE_QM_TX_Q);
352     /* Force the packet to EMAC port 0 if loopback is enabled */
353     hd->packetInfo |= (1<<16);
355     hwQmQueuePush (hd, DEVICE_QM_ETH_TX_Q, QM_DESC_SIZE_BYTES);
357     return (0);
362 int32_t targetMacRcv (void *vptr_device, uint8_t *buffer)
364     int32_t           pktSizeBytes;
365     qmHostDesc_t   *hd;
367     hd = hwQmQueuePop (DEVICE_QM_RCV_Q);
368     if (hd == NULL)
369         return (0);
371     pktSizeBytes = QM_DESC_DESCINFO_GET_PKT_LEN(hd->descInfo);
372     iblMemcpy ((void *)buffer, (void *)hd->buffPtr, pktSizeBytes);
374     hd->buffLen = hd->origBufferLen;
375     hd->buffPtr = hd->origBuffPtr;
377     hwQmQueuePush (hd, DEVICE_QM_LNK_BUF_Q, QM_DESC_SIZE_BYTES);
379     return (pktSizeBytes);
383 void targetFreeQs (void)
385     qmHostDesc_t   *hd;
387     do  {
389         hd = hwQmQueuePop (DEVICE_QM_FREE_Q);
391     } while (hd != NULL);
393     do  {
395         hd = hwQmQueuePop (DEVICE_QM_LNK_BUF_Q);
397     } while (hd != NULL);
399     do  {
401         hd = hwQmQueuePop (DEVICE_QM_RCV_Q);
403     } while (hd != NULL);
405     do  {
407         hd = hwQmQueuePop (DEVICE_QM_TX_Q);
409     } while (hd != NULL);