1 /******************************************************************************
2 * Copyright (c) 2011-12 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 #include <string.h>
35 #include "platform.h"
36 #include "types.h"
37 #include "post.h"
38 #include "target.h"
39 #include "pscapi.h"
41 #if !(defined(_EVMC6657L_))
42 #include "net.h"
43 #include "cpmacdrv.h"
44 #include "qm_api.h"
45 #include "cpdma_api.h"
46 #else
47 #include "evmc665x_phy.h"
48 #include "evmc665x_emac.h"
49 #endif
51 /* CSL EMAC include */
52 #if !(defined(_EVMC6657L_))
53 #include <ti/csl/csl_cpsw.h>
54 #include <ti/csl/csl_cpsgmii.h>
55 #include <ti/csl/csl_cpsgmiiAux.h>
56 #include <ti/csl/cslr_cpsgmii.h>
57 #include <ti/csl/csl_mdioAux.h>
58 #else
59 #include <ti/csl/csl_sgmii.h>
60 #include <ti/csl/cslr_sgmii.h>
61 #endif
63 #include <ti/csl/csl_mdio.h>
65 /* BootCfg module include */
66 #include <ti/csl/csl_bootcfg.h>
67 #include <ti/csl/csl_bootcfgAux.h>
69 /* The version string */
70 #pragma DATA_SECTION(post_version, ".version")
71 #pragma DATA_ALIGN(post_version, 16)
72 char post_version[] = POST_VERSION;
74 /* OSAL functions for Platform Library */
75 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
76 {
77 return malloc(num_bytes);
78 }
80 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
81 {
82 /* Free up the memory */
83 if (dataPtr)
84 {
85 free(dataPtr);
86 }
87 }
89 /******************************************************************************
90 * Function: post_display_led_error
91 ******************************************************************************/
92 void
93 post_display_led_error
94 (
95 POST_TEST_ID test_id
96 )
97 {
98 uint8_t led_status[POST_MAX_NUM_LED];
99 uint32_t i;
101 memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
102 while (TRUE)
103 {
104 for (i = 0; i < POST_MAX_NUM_LED; i++)
105 {
106 if (post_led_status[test_id][i] == POST_LED_BLINK)
107 {
108 if (led_status[i] == POST_LED_ON)
109 {
110 led_status[i] = POST_LED_OFF;
111 }
112 else
113 {
114 led_status[i] = POST_LED_ON;
115 }
116 platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS);
117 }
118 else
119 {
120 platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS);
121 }
122 }
123 platform_delay(POST_LED_BLINK_DELAY);
124 /* POST in the while(1) loop to display the LED error status */
125 }
126 }
128 /******************************************************************************
129 * Function: post_write_uart
130 ******************************************************************************/
131 Bool
132 post_write_uart
133 (
134 char* msg
135 )
136 {
137 uint32_t i;
138 uint32_t msg_len = strlen(msg);
140 /* Write the message to the UART */
141 for (i = 0; i < msg_len; i++)
142 {
143 if (platform_uart_write(msg[i]) != Platform_EOK)
144 {
145 return FALSE;
146 }
147 }
149 return TRUE;
150 }
152 /******************************************************************************
153 * Function: post_display_status
154 ******************************************************************************/
155 void
156 post_display_status
157 (
158 POST_TEST_ID test_id,
159 POST_TEST_RESULT test_result
160 )
161 {
162 uint32_t i;
163 char *msg;
164 char msg1[40] = "\r\n\rPOST ";
165 char msg2[] = " test passed!";
166 char msg3[] = " test failed!";
167 char msg4[] = " test started!";
169 msg = strcat(msg1, post_status[test_id]);
170 switch (test_id)
171 {
172 case POST_TEST_IN_PROGRESS:
173 case POST_TEST_COMPLETE:
174 /* Form the POST status message to write to the UART */
175 if (post_write_uart(msg) != TRUE)
176 {
177 post_display_led_error(POST_TEST_UART); /* Never return from this function */
178 }
180 for (i = 0; i < POST_MAX_NUM_LED; i++)
181 {
182 if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK)
183 {
184 post_write_uart("POST LED test failed \r\n");
185 }
186 }
187 break;
189 default:
190 /* Form the POST status message to write to the UART */
191 if (test_result == POST_TEST_RESULT_PASSED)
192 {
193 msg = strcat(msg, msg2);
194 if (post_write_uart(msg) != TRUE)
195 {
196 post_display_led_error(POST_TEST_UART); /* Never return from this function */
197 }
198 }
199 else if (test_result == POST_TEST_RESULT_FAILED)
200 {
201 msg = strcat(msg, msg3);
202 if (post_write_uart(msg) != TRUE)
203 {
204 post_display_led_error(POST_TEST_UART); /* Never return from this function */
205 }
206 post_display_led_error(test_id); /* Never return from this function */
207 }
208 else
209 {
210 msg = strcat(msg, msg4);
211 if (post_write_uart(msg) != TRUE)
212 {
213 post_display_led_error(POST_TEST_UART); /* Never return from this function */
214 }
215 }
216 break;
217 }
218 }
220 /******************************************************************************
221 * Function: post_test_external_memory
222 ******************************************************************************/
223 POST_TEST_RESULT
224 post_test_external_memory
225 (
226 void
227 )
228 {
229 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
231 if(platform_external_memory_test(0, 0) != Platform_EOK)
232 {
233 test_result = POST_TEST_RESULT_FAILED;
234 }
236 return test_result;
237 }
239 /******************************************************************************
240 * Function: post_test_eeprom
241 ******************************************************************************/
242 POST_TEST_RESULT
243 post_test_eeprom
244 (
245 void
246 )
247 {
248 uint8_t test_buf[POST_EEPROM_TEST_READ_LENGTH];
249 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
250 PLATFORM_DEVICE_info *p_device;
252 p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
253 if (p_device == NULL)
254 {
255 return POST_TEST_RESULT_FAILED;
256 }
258 if(platform_device_read(p_device->handle,
259 POST_EEPROM_TEST_READ_ADDRESS,
260 test_buf,
261 POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK)
262 {
263 test_result = POST_TEST_RESULT_FAILED;
264 }
266 platform_device_close(p_device->handle);
267 return test_result;
268 }
270 /******************************************************************************
271 * Function: post_test_nand
272 ******************************************************************************/
273 POST_TEST_RESULT
274 post_test_nand
275 (
276 void
277 )
278 {
279 uint8_t test_buf[POST_NAND_TEST_READ_LENGTH];
280 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
281 uint32_t addr;
282 PLATFORM_DEVICE_info *p_device;
284 p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
285 if (p_device == NULL)
286 {
287 return POST_TEST_RESULT_FAILED;
288 }
290 addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
291 if(platform_device_read(p_device->handle,
292 addr,
293 test_buf,
294 POST_NAND_TEST_READ_LENGTH) != Platform_EOK)
295 {
296 test_result = POST_TEST_RESULT_FAILED;
297 }
299 platform_device_close(p_device->handle);
300 return test_result;
301 }
303 /******************************************************************************
304 * Function: post_test_nor
305 ******************************************************************************/
306 POST_TEST_RESULT
307 post_test_nor
308 (
309 void
310 )
311 {
312 uint8_t test_buf[POST_NOR_TEST_READ_LENGTH];
313 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
314 PLATFORM_DEVICE_info *p_device;
316 p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
317 if (p_device == NULL)
318 {
319 return POST_TEST_RESULT_FAILED;
320 }
322 if(platform_device_read(p_device->handle,
323 POST_NOR_TEST_READ_ADDR,
324 test_buf,
325 POST_NOR_TEST_READ_LENGTH) != Platform_EOK)
326 {
327 test_result = POST_TEST_RESULT_FAILED;
328 }
330 platform_device_close(p_device->handle);
331 return test_result;
332 }
333 #if !(defined(_EVMC6657L_))
334 /** Number of ports in the ethernet subsystem */
335 #define NUM_PORTS 3u
337 /** Number of MAC/GMII ports in the ethernet switch */
338 #define NUM_MAC_PORTS 2u
341 #else
342 /** Number of ports in the ethernet subsystem */
343 #define NUM_PORTS 1u
345 /** Number of MAC/GMII ports in the ethernet switch */
346 #define NUM_MAC_PORTS 1u
348 #endif
350 /*Define LoopBack Mode for C6657*/
351 #define MAC_LOOPBACK (1 << 0)
352 #define EXT_COPPER_LOOPBACK (1 << 3)
353 #define EXT_FIBER_LOOPBACK (1 << 4)
355 /* Define LoopBack modes for C6678 & C6670*/
356 #define CPSW_LOOPBACK_NONE 0
357 #define CPSW_LOOPBACK_INTERNAL 1
358 #define CPSW_LOOPBACK_EXTERNAL 2
360 #ifdef SIMULATOR_SUPPORT
361 int32_t cpswSimTest = 1;
362 int32_t cpswLpbkMode = CPSW_LOOPBACK_EXTERNAL;
363 #else
364 int32_t LpbkMode = EXT_COPPER_LOOPBACK;
365 int32_t cpswSimTest = 0;
366 int32_t cpswLpbkMode = CPSW_LOOPBACK_INTERNAL;
367 #endif
368 int32_t cpswEvm6678 = 0;
370 #if !(defined(_EVMC6657L_))
371 /** ============================================================================
372 * @n@b Init_SGMII
373 *
374 * @b Description
375 * @n SGMII peripheral initialization code.
376 *
377 * @param[in]
378 * @n macPortNum MAC port number for which the SGMII port setup must
379 * be performed.
380 *
381 * @return
382 * @n None
383 * =============================================================================
384 */
385 int32_t Init_sgmii (uint32_t macPortNum)
386 {
387 CSL_SGMII_ADVABILITY sgmiiCfg;
388 CSL_SGMII_STATUS sgmiiStatus;
390 if ((macPortNum == 0) && (cpswEvm6678))
391 {
392 /* EVM6678 back end: MAC-to-MAC force link */
394 /* Reset the port before configuring it */
395 CSL_SGMII_doSoftReset (macPortNum);
396 while (CSL_SGMII_getSoftResetStatus (macPortNum) != 0);
398 /* Hold the port in soft reset and set up
399 * the SGMII control register:
400 * (1) Enable Master Mode (default)
401 */
402 CSL_SGMII_startRxTxSoftReset (macPortNum);
403 CSL_SGMII_enableMasterMode (macPortNum);
404 if (cpswLpbkMode != CPSW_LOOPBACK_NONE)
405 {
406 CSL_SGMII_enableLoopback (macPortNum);
407 }
409 /* Setup the Advertised Ability register for this port:
410 * (1) Enable Full duplex mode
411 * (2) Speed = 1000M
412 * (3) Force the Link
413 */
414 sgmiiCfg.bLinkUp = 1;
415 sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS;
416 sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX;
417 CSL_SGMII_setAdvAbility (macPortNum, &sgmiiCfg);
419 CSL_SGMII_endRxTxSoftReset (macPortNum);
421 /* Wait for SGMII Link */
422 do
423 {
424 CSL_SGMII_getStatus(macPortNum, &sgmiiStatus);
425 } while (sgmiiStatus.bIsLinkUp != 1);
426 }
427 else
428 {
429 /* Reset the port before configuring it */
430 CSL_SGMII_doSoftReset (macPortNum);
431 while (CSL_SGMII_getSoftResetStatus (macPortNum) != 0);
433 /* Hold the port in soft reset and set up
434 * the SGMII control register:
435 * (1) Enable Master Mode (default)
436 * (2) Enable Auto-negotiation
437 */
438 CSL_SGMII_startRxTxSoftReset (macPortNum);
439 if (cpswLpbkMode == CPSW_LOOPBACK_NONE)
440 {
441 CSL_SGMII_disableMasterMode (macPortNum);
442 }
443 else
444 {
445 CSL_SGMII_enableMasterMode (macPortNum);
447 if (cpswLpbkMode == CPSW_LOOPBACK_INTERNAL)
448 {
449 CSL_SGMII_enableLoopback (macPortNum);
450 }
451 }
453 /* Setup the Advertised Ability register for this port:
454 * (1) Enable Full duplex mode
455 * (2) Enable Auto Negotiation
456 */
457 sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS;
458 sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX;
459 CSL_SGMII_setAdvAbility (macPortNum, &sgmiiCfg);
461 CSL_SGMII_enableAutoNegotiation (macPortNum);
462 CSL_SGMII_endRxTxSoftReset (macPortNum);
464 /* Wait for SGMII Link */
465 if (!cpswSimTest)
466 {
467 do
468 {
469 CSL_SGMII_getStatus(macPortNum, &sgmiiStatus);
470 } while (sgmiiStatus.bIsLinkUp != 1);
472 /* Wait for SGMII Autonegotiation to complete without error */
473 do
474 {
475 CSL_SGMII_getStatus(macPortNum, &sgmiiStatus);
476 if (sgmiiStatus.bIsAutoNegError != 0)
477 return -1;
478 } while (sgmiiStatus.bIsAutoNegComplete != 1);
479 }
480 }
482 /* All done with configuration. Return Now. */
483 return 0;
484 }
486 int Init_MAC (uint32_t macPortNum, uint8_t macAddress[6], uint32_t mtu)
487 {
488 /* Reset MAC Sliver 0 */
489 CSL_CPGMAC_SL_resetMac (macPortNum);
490 while (CSL_CPGMAC_SL_isMACResetDone (macPortNum) != TRUE);
492 /* Setup the MAC Control Register for this port:
493 * (1) Enable Full duplex
494 * (2) Enable GMII
495 * (3) Enable Gigabit
496 * (4) Enable External Configuration. This enables
497 * the "Full duplex" and "Gigabit" settings to be
498 * controlled externally from SGMII
499 * (5) Don't enable any control/error/short frames
500 */
501 CSL_CPGMAC_SL_enableFullDuplex (macPortNum);
502 CSL_CPGMAC_SL_enableGMII (macPortNum);
503 CSL_CPGMAC_SL_enableGigabit (macPortNum);
504 CSL_CPGMAC_SL_enableExtControl (macPortNum);
506 /* Configure the MAC address for this port */
507 CSL_CPSW_3GF_setPortMACAddress (macPortNum, macAddress);
509 /* Configure VLAN ID/CFI/Priority.
510 *
511 * For now, we are not using VLANs so just configure them
512 * to all zeros.
513 */
514 CSL_CPSW_3GF_setPortVlanReg (macPortNum, 0, 0, 0);
516 /* Configure the Receive Maximum length on this port,
517 * i.e., the maximum size the port can receive without
518 * any errors.
519 *
520 * Set the Rx Max length to the MTU configured for the
521 * interface.
522 */
523 CSL_CPGMAC_SL_setRxMaxLen (macPortNum, mtu);
525 /* Done setting up the MAC port */
526 return 0;
527 }
529 void Init_Switch (uint32_t mtu)
530 {
531 CSL_CPSW_3GF_PORTSTAT portStatCfg;
533 /* Enable the CPPI port, i.e., port 0 that does all
534 * the data streaming in/out of EMAC.
535 */
536 CSL_CPSW_3GF_enablePort0 ();
537 CSL_CPSW_3GF_disableVlanAware ();
538 CSL_CPSW_3GF_setPort0VlanReg (0, 0, 0);
539 CSL_CPSW_3GF_setPort0RxMaxLen (mtu);
541 /* Enable statistics on both the port groups:
542 *
543 * MAC Sliver ports - Port 1, Port 2
544 * CPPI Port - Port 0
545 */
546 portStatCfg.p0AStatEnable = 1;
547 portStatCfg.p0BStatEnable = 1;
548 portStatCfg.p1StatEnable = 1;
549 portStatCfg.p2StatEnable = 1;
550 CSL_CPSW_3GF_setPortStatsEnableReg (&portStatCfg);
552 /* Setup the Address Lookup Engine (ALE) Configuration:
553 * (1) Enable ALE.
554 * (2) Clear stale ALE entries.
555 * (3) Disable VLAN Aware lookups in ALE since
556 * we are not using VLANs by default.
557 * (4) No Flow control
558 * (5) Configure the Unknown VLAN processing
559 * properties for the switch, i.e., which
560 * ports to send the packets to.
561 */
562 CSL_CPSW_3GF_enableAle ();
563 CSL_CPSW_3GF_clearAleTable ();
565 CSL_CPSW_3GF_disableAleVlanAware ();
566 CSL_CPSW_3GF_disableAleTxRateLimit ();
567 CSL_CPSW_3GF_setAlePrescaleReg (125000000u/1000u);
568 CSL_CPSW_3GF_setAleUnkownVlanReg (7, 3, 3, 7);
570 if(cpswLpbkMode != CPSW_LOOPBACK_NONE)
571 CSL_CPSW_3GF_enableAleBypass();
573 /* Done with switch configuration */
574 return;
575 }
577 int Switch_update_addr (uint32_t portNum, uint8_t macAddress[6], Uint16 add)
578 {
579 uint32_t i;
580 CSL_CPSW_3GF_ALE_PORTCONTROL alePortControlCfg;
581 CSL_CPSW_3GF_ALE_UNICASTADDR_ENTRY ucastAddrCfg;
584 /* Configure the address in "Learning"/"Forward" state */
585 alePortControlCfg.portState = ALE_PORTSTATE_FORWARD;
586 alePortControlCfg.dropUntaggedEnable = 0;
587 alePortControlCfg.vidIngressCheckEnable = 0;
588 alePortControlCfg.noLearnModeEnable = (cpswLpbkMode != CPSW_LOOPBACK_NONE)?1:0;
589 alePortControlCfg.mcastLimit = 0;
590 alePortControlCfg.bcastLimit = 0;
592 CSL_CPSW_3GF_setAlePortControlReg (portNum, &alePortControlCfg);
594 if (cpswLpbkMode != CPSW_LOOPBACK_NONE)
595 {
596 /* Program the ALE with the MAC address.
597 *
598 * The ALE entries determine the switch port to which any
599 * matching received packet must be forwarded to.
600 */
601 /* Get the next free ALE entry to program */
602 for (i = 0; i < CSL_CPSW_3GF_NUMALE_ENTRIES; i++)
603 {
604 if (CSL_CPSW_3GF_getALEEntryType (i) == ALE_ENTRYTYPE_FREE)
605 {
606 /* Found a free entry */
607 break;
608 }
609 }
610 if (i == CSL_CPSW_3GF_NUMALE_ENTRIES)
611 {
612 /* No free ALE entry found. return error. */
613 return -1;
614 }
615 else
616 {
617 /* Found a free ALE entry to program our MAC address */
618 memcpy (ucastAddrCfg.macAddress, macAddress, 6); // Set the MAC address
619 ucastAddrCfg.ucastType = ALE_UCASTTYPE_UCAST_NOAGE; // Add a permanent unicast address entryALE_UCASTTYPE_UCAST_NOAGE.
620 ucastAddrCfg.secureEnable = FALSE;
621 ucastAddrCfg.blockEnable = FALSE;
622 ucastAddrCfg.portNumber = portNum; // Add the ALE entry for this port
624 /* Setup the ALE entry for this port's MAC address */
625 CSL_CPSW_3GF_setAleUnicastAddrEntry (i, &ucastAddrCfg);
626 }
627 }
629 /* Done with upading address */
630 return 0;
631 }
633 int32_t Init_SGMII_SERDES(void)
634 {
635 if (cpswSimTest)
636 {
638 /* Unlock the chip configuration registers to allow SGMII SERDES registers to
639 * be written */
640 CSL_BootCfgUnlockKicker();
642 CSL_BootCfgSetSGMIIConfigPLL (0x00000041);
643 CSL_BootCfgSetSGMIIRxConfig (0, 0x00700621);
644 CSL_BootCfgSetSGMIITxConfig (0, 0x000108A1);
645 CSL_BootCfgSetSGMIIRxConfig (1, 0x00700621);
646 CSL_BootCfgSetSGMIITxConfig (1, 0x000108A1);
648 /* Re-lock the chip configuration registers to prevent unintentional writes */
649 CSL_BootCfgLockKicker();
651 }
653 /* SGMII SERDES Configuration complete. Return. */
654 return 0;
655 }
657 int32_t Init_Cpsw (void)
658 {
659 uint32_t macPortNum, mtu = 1518;
660 uint8_t mac_address[6];
661 uint8_t sw_port0_mac_addr[6] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
663 /* Initialize the SERDES modules */
664 Init_SGMII_SERDES();
666 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address);
668 /* Initialize the SGMII/Sliver submodules for the
669 * two corresponding MAC ports.
670 */
671 for (macPortNum = 0; macPortNum < NUM_MAC_PORTS; macPortNum++)
672 {
673 if (Init_sgmii (macPortNum))
674 return -1;
675 mac_address[5] += macPortNum;
676 Init_MAC (macPortNum, mac_address, mtu);
677 mac_address[5] -= macPortNum;
678 }
680 /* Setup the Ethernet switch finally. */
681 Init_Switch (mtu);
683 Switch_update_addr(0, sw_port0_mac_addr, 0);
684 Switch_update_addr(1, mac_address, 0);
685 mac_address[5] += 1;
686 Switch_update_addr(2, mac_address, 0);
688 /* CPSW subsystem setup done. Return success */
689 return 0;
690 }
692 #endif
694 /******************************************************************************
695 * Function: post_test_emac_loopback
696 ******************************************************************************/
697 POST_TEST_RESULT
698 post_test_emac_loopback
699 (
700 void
701 )
702 {
703 uint8_t test_buf[POST_EMAC_TEST_PKT_LENGTH+14];
704 #if (defined(_EVMC6657L_))
705 SGMII_Config config;
706 uint8_t mac_address[6];
707 #endif
709 #if !(defined(_EVMC6657L_))
710 uint8_t sw_port0_mac_addr[6] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
711 uint8_t mac_address[6];
712 uint8_t ret;
713 NET_DRV_DEVICE nDevice;
714 #endif
717 #if !(defined(_EVMC6657L_))
718 int modNum = 8;
719 if (modNum == TARGET_PWR_ETH(x)) {
720 ret = (int32_t)pscEnableModule (TARGET_PWR_PA);
721 if (ret != 0)
722 return (POST_TEST_RESULT_FAILED);
723 }
724 #endif
727 #if !(defined(_EVMC6657L_))
728 Init_Cpsw();
730 /* Queue manager configuration */
731 hwQmSetup ((qmConfig_t *)(targetGetQmConfig()));
732 targetInitQs ();
735 /* Cpdma configuration. */
736 hwCpdmaRxConfig ((cpdmaRxCfg_t *)targetGetCpdmaRxConfig());
737 hwCpdmaTxConfig ((cpdmaTxCfg_t *)targetGetCpdmaTxConfig());
740 /* Packet accelerator configuration. If PA is not present this statement is defined
741 * to void in target.h */
742 targetPaConfig(sw_port0_mac_addr);
744 /* Streaming switch configuration. If not present this statement is defined to void
745 * in target.h. If present this is usually defined to a series of register writes */
746 hwConfigStreamingSwitch();
748 /* Initialize the network device driver */
749 memset (&nDevice, 0, sizeof(nDevice));
751 /* Start the networking device */
752 if (cpmac_drv_start(&nDevice) < 0)
753 {
754 return POST_TEST_RESULT_FAILED;
755 }
757 /* Get the MAC address from efuse */
758 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address);
760 /* Set the dest MAC address to be broadcast, so that PA firmware will not filter out */
761 memset(test_buf, 0xff, 6);
762 memcpy(&test_buf[6], sw_port0_mac_addr, 6);
764 /* set the payload length to 256 bytes */
765 test_buf[12] = 0x01;
766 test_buf[13] = 0x00;
768 /* Send the Ethernet packet */
769 if (cpmac_drv_send (&nDevice, test_buf, POST_EMAC_TEST_PKT_LENGTH+14) < 0)
770 {
771 return POST_TEST_RESULT_FAILED;
772 }
774 platform_delay(100);
776 /* Receive the loopback packet */
777 if (ret = cpmac_drv_receive (&nDevice, test_buf) <= 0)
778 {
779 return POST_TEST_RESULT_FAILED;
780 }
782 #else
783 sgmii_init();
784 EMAC_init();
785 config.loopbackEn = 1;
786 SGMII_config(&config);
788 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address);
790 /* Set the dest MAC address to be broadcast, so that PA firmware will not filter out */
791 memset(test_buf, 0xff, 6);
792 memcpy(&test_buf[6], mac_address, 6);
794 /* set the payload length to 256 bytes */
795 test_buf[12] = 0x01;
796 test_buf[13] = 0x00;
798 if(EMAC_Send(test_buf, POST_EMAC_TEST_PKT_LENGTH+14) < 0)
799 {
800 return POST_TEST_RESULT_FAILED;
801 }
803 platform_delay(1000);
805 if(EMAC_Recv(test_buf) <= 0)
806 {
807 return POST_TEST_RESULT_FAILED;
808 }
810 #endif
811 return POST_TEST_RESULT_PASSED;
812 }
814 void
815 post_hex_to_string
816 (
817 uint32_t hex,
818 uint32_t nibbles,
819 char *msg
820 )
821 {
822 int32_t i;
823 uint8_t nibble;
825 for (i = (nibbles-1); i >= 0; i--)
826 {
827 nibble = hex & 0xf;
828 if (nibble <= 0x9)
829 {
830 nibble += '0';
831 }
832 else
833 {
834 nibble += ('A' - 0xa);
835 }
837 msg[i] = nibble;
838 hex = hex >> 4;
839 }
840 msg[nibbles] = 0;
841 }
843 Bool
844 post_serial_num_isvalid
845 (
846 char c
847 )
848 {
849 if (
850 ((c >= '0') && (c <= '9')) ||
851 ((c >= 'a') && (c <= 'z')) ||
852 ((c >= 'A') && (c <= 'Z'))
853 )
854 {
855 return TRUE;
856 }
857 else
858 {
859 return FALSE;
860 }
861 }
863 /******************************************************************************
864 * Function: post_write_serial_no
865 ******************************************************************************/
866 void
867 post_write_serial_no
868 (
869 void
870 )
871 {
872 uint32_t i, j;
873 uint8_t msg[20], msg2[2];
874 PLATFORM_DEVICE_info *p_device;
876 /* Check if user key in the passcode "ti" to enter board serial number */
877 if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
878 {
879 return;
880 }
881 if (msg[0] != 't')
882 {
883 return;
884 }
886 if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
887 {
888 return;
889 }
890 if (msg[0] != 'i')
891 {
892 return;
893 }
895 /* Passcode verified, prompt the user to enter serial number */
896 p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
897 if (p_device == NULL)
898 {
899 return;
900 }
902 post_write_uart("\r\n\r\nPlease enter the 10 digit serial number for this board, and then press ENTER key:\r\n\r\n");
904 i = 0;
905 msg2[1] = 0;
906 while (TRUE)
907 {
908 if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK)
909 {
910 platform_device_close(p_device->handle);
911 post_write_uart("\r\n\r\nSerial number input time out!");
912 return;
913 }
915 if (msg[i] == '\r')
916 {
917 break;
918 }
919 if ((i < POST_MAX_SN_SIZE) && post_serial_num_isvalid(msg[i]))
920 {
921 msg2[0] = msg[i];
922 post_write_uart((char *)msg2);
923 i++;
924 }
925 }
927 if (i < POST_MAX_SN_SIZE)
928 {
929 for (j = i; j < POST_MAX_SN_SIZE; j++)
930 {
931 msg[j] = 0xff;
932 }
933 }
935 if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
936 {
937 post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
938 }
939 else
940 {
941 post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!");
942 }
943 platform_device_close(p_device->handle);
945 }
947 /******************************************************************************
948 * Function: post_dump_register_val
949 ******************************************************************************/
950 void
951 post_dump_register_val
952 (
953 uint32_t reg_addr,
954 char* desc_string
955 )
956 {
957 char msg[10];
958 uint32_t reg_val;
960 reg_val = *(volatile uint32_t *)reg_addr;
961 post_write_uart(desc_string);
962 post_hex_to_string(reg_val, 8, msg);
963 msg[8] = ' ';
964 msg[9] = 0;
965 post_write_uart(msg);
966 }
968 /******************************************************************************
969 * Function: main function for POST
970 ******************************************************************************/
971 void
972 main
973 (
974 void
975 )
976 {
977 platform_init_flags init_flags;
978 platform_init_config init_config;
979 POST_TEST_ID test_id = POST_TEST_IN_PROGRESS;
980 POST_TEST_RESULT test_result;
981 uint32_t reset_type;
982 int32_t i;
983 char msg[9];
984 uint8_t mac_addr[6];
985 platform_info info;
986 #if !(defined(_EVMC6657L_)||defined(_EVMC6655L_))
987 uint32_t sa_enable;
988 #endif
989 uint32_t acc_fail;
990 extern uint32_t platform_init_return_code;
992 /* Turn on all the platform initialize flags */
993 memset(&init_config, 0, sizeof(platform_init_config));
994 memset(&init_flags, 0x01, sizeof(platform_init_flags));
996 init_flags.phy = 1;
997 acc_fail = 0;
999 /* Initialize the platform */
1000 if (platform_init(&init_flags, &init_config) != Platform_EOK)
1001 {
1002 switch (platform_errno)
1003 {
1004 case PLATFORM_ERRNO_PLL_SETUP:
1005 test_id = POST_TEST_PLL_INIT;
1006 break;
1007 case PLATFORM_ERRNO_NAND:
1008 test_id = POST_TEST_NAND_INIT;
1009 break;
1010 case PLATFORM_ERRNO_NOR:
1011 test_id = POST_TEST_NOR_INIT;
1012 break;
1013 default:
1014 test_id = POST_TEST_GENERAL;
1015 break;
1016 }
1017 test_result = POST_TEST_RESULT_FAILED;
1018 }
1019 if (test_result == POST_TEST_RESULT_FAILED)
1020 {
1021 acc_fail++;
1022 }
1023 platform_uart_init();
1024 platform_uart_set_baudrate(POST_UART_BAUDRATE);
1025 if (test_id != POST_TEST_PLL_INIT)
1026 {
1027 if (post_write_uart("\r\n\r\n") != TRUE)
1028 {
1029 post_display_led_error(POST_TEST_UART); /* Never return from this function */
1030 }
1032 platform_get_info(&info);
1034 /* Display the board name */
1035 post_write_uart(info.board_name);
1037 /* Display the POST version */
1038 post_write_uart(POST_EVM_VERSION_MSG);
1039 post_write_uart(post_version);
1041 post_write_uart("\r\n\r------------------------------------------");
1042 post_write_uart("\r\n\rSOC Information");
1043 post_hex_to_string(info.board_rev, 4, msg);
1044 post_write_uart("\r\n\r\nFPGA Version: ");
1045 post_write_uart(msg);
1047 if (info.serial_nbr[0] != 0)
1048 {
1049 post_write_uart("\r\n\rBoard Serial Number: ");
1050 post_write_uart(info.serial_nbr);
1051 }
1053 /* Display the EFUSE MAC address */
1054 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr);
1055 post_write_uart("\r\n\rEFUSE MAC ID is: ");
1056 for (i = 0; i < 6; i++)
1057 {
1058 post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg);
1059 msg[2] = ' ';
1060 msg[3] = 0;
1061 post_write_uart(msg);
1062 }
1063 #if !(defined(_EVMC6657L_)||defined(_EVMC6655L_))
1064 sa_enable = *(volatile uint32_t *)0x20c0004;
1065 sa_enable &= 0x1;
1067 if (sa_enable)
1068 {
1069 post_write_uart("\r\n\rSA is enabled on this board.");
1070 }
1071 else
1072 {
1073 post_write_uart("\r\n\rSA is disabled on this board.");
1074 }
1075 #endif
1076 /* Read the PLL Reset Type Status register and display on UART */
1077 reset_type = PLL_CTRL_REG_RSTYPE;
1078 post_hex_to_string(reset_type, 8, msg);
1079 post_write_uart("\r\n\rPLL Reset Type Status Register: 0x");
1080 post_write_uart(msg);
1082 /* Dump Additional Information */
1083 post_dump_register_val ((uint32_t)&platform_init_return_code, "\r\n\rPlatform init return code: 0x");
1084 post_write_uart("\r\n\rAdditional Information: ");
1085 post_dump_register_val (0x02350014, "\r\n\r (0x02350014) :");
1086 post_dump_register_val (0x02350624, "\r\n\r (0x02350624) :");
1087 post_dump_register_val (0x02350678, "\r\n\r (0x02350678) :");
1088 post_dump_register_val (0x0235063C, "\r\n\r (0x0235063C) :");
1089 post_dump_register_val (0x02350640, "\r\n\r (0x02350640) :");
1090 post_dump_register_val (0x02350644, "\r\n\r (0x02350644) :");
1091 post_dump_register_val (0x02350648, "\r\n\r (0x02350648) :");
1092 post_dump_register_val (0x0235064C, "\r\n\r (0x0235064C) :");
1093 post_dump_register_val (0x02350650, "\r\n\r (0x02350650) :");
1094 post_dump_register_val (0x02350654, "\r\n\r (0x02350654) :");
1095 post_dump_register_val (0x02350658, "\r\n\r (0x02350658) :");
1096 post_dump_register_val (0x0235065C, "\r\n\r (0x0235065C) :");
1097 post_dump_register_val (0x02350660, "\r\n\r (0x02350660) :");
1098 post_dump_register_val (0x02350668, "\r\n\r (0x02350668) :");
1099 post_dump_register_val (0x02350670, "\r\n\r (0x02350670) :");
1101 post_dump_register_val (0x02620008, "\r\n\r (0x02620008) :");
1102 post_dump_register_val (0x0262000c, "\r\n\r (0x0262000c) :");
1103 post_dump_register_val (0x02620010, "\r\n\r (0x02620010) :");
1104 post_dump_register_val (0x02620014, "\r\n\r (0x02620014) :");
1105 post_dump_register_val (0x02620018, "\r\n\r (0x02620018) :");
1106 post_dump_register_val (0x02620180, "\r\n\r (0x02620180) :");
1108 post_write_uart("\r\n\r------------------------------------------");
1109 }
1111 post_write_uart("\r\n\r\nPower On Self Test\n");
1113 /* Display test in progress UART/LED status or init error */
1114 post_display_status(test_id, POST_TEST_RESULT_STARTED);
1116 post_display_status(POST_TEST_EEPROM, POST_TEST_RESULT_STARTED);
1117 test_result = post_test_eeprom();
1118 if (test_result == POST_TEST_RESULT_FAILED)
1119 {
1120 acc_fail++;
1121 }
1122 post_display_status(POST_TEST_EEPROM, test_result);
1124 post_display_status(POST_TEST_NOR, POST_TEST_RESULT_STARTED);
1125 test_result = post_test_nor();
1126 if (test_result == POST_TEST_RESULT_FAILED)
1127 {
1128 acc_fail++;
1129 }
1130 post_display_status(POST_TEST_NOR, test_result);
1132 post_display_status(POST_TEST_NAND, POST_TEST_RESULT_STARTED);
1133 test_result = post_test_nand();
1134 if (test_result == POST_TEST_RESULT_FAILED)
1135 {
1136 acc_fail++;
1137 }
1138 post_display_status(POST_TEST_NAND, test_result);
1140 post_display_status(POST_TEST_EMAC_LOOPBACK, POST_TEST_RESULT_STARTED);
1141 test_result = post_test_emac_loopback();
1142 if (test_result == POST_TEST_RESULT_FAILED)
1143 {
1144 acc_fail++;
1145 }
1146 post_display_status(POST_TEST_EMAC_LOOPBACK, test_result);
1148 post_display_status(POST_TEST_DDR, POST_TEST_RESULT_STARTED);
1149 test_result = post_test_external_memory();
1150 if (test_result == POST_TEST_RESULT_FAILED)
1151 {
1152 acc_fail++;
1153 }
1154 post_display_status(POST_TEST_DDR, test_result);
1156 post_display_status(POST_TEST_COMPLETE, POST_TEST_RESULT_PASSED);
1158 if (acc_fail == 0)
1159 {
1160 post_write_uart("\r\n\r\nPOST result: PASS");
1161 }
1162 else
1163 {
1164 post_write_uart("\r\n\r\nPOST result: FAIL");
1165 }
1167 post_write_serial_no();
1168 }