summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSam Nelson2015-09-23 17:22:45 -0500
committerSam Nelson2015-09-23 17:22:45 -0500
commit30e875d109637efaa7066ea84f5e0ab40caf5b29 (patch)
tree4ef77f69ae36334c4bc1ee7f3ec8b1599d6e8d32 /src
parent2095d8b7b4bb3c2902c855486d272df9fdfb8d5e (diff)
downloadmpm-transport-30e875d109637efaa7066ea84f5e0ab40caf5b29.tar.gz
mpm-transport-30e875d109637efaa7066ea84f5e0ab40caf5b29.tar.xz
mpm-transport-30e875d109637efaa7066ea84f5e0ab40caf5b29.zip
hyplnk: Update with cleanup and ECC error handlingDEV.MPM-TRANSPORT-01.00.08.02A
Signed-off-by: Sam Nelson <sam.nelson@ti.com>
Diffstat (limited to 'src')
-rw-r--r--src/transport/hyplnk/mpm_transport_hyplnk_interface.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/src/transport/hyplnk/mpm_transport_hyplnk_interface.c b/src/transport/hyplnk/mpm_transport_hyplnk_interface.c
index 918be33..a8f20fd 100644
--- a/src/transport/hyplnk/mpm_transport_hyplnk_interface.c
+++ b/src/transport/hyplnk/mpm_transport_hyplnk_interface.c
@@ -41,6 +41,7 @@ extern hyplnk_peripheral hyplnkActiveIF[NUM_INTERFACES];
41 41
42#define SERDES_DIRECTION_TX 0x1 42#define SERDES_DIRECTION_TX 0x1
43#define SERDES_DIRECTION_RX 0x2 43#define SERDES_DIRECTION_RX 0x2
44#define SERDES_DIRECTION_RX_RESET 0x4
44 45
45void * internal_hyplnk_mmap(uint32_t addr, uint32_t size, int device_fd) 46void * internal_hyplnk_mmap(uint32_t addr, uint32_t size, int device_fd)
46{ 47{
@@ -322,7 +323,7 @@ int hyplnkSerdesSetup(mpm_transport_hyplnk_t *hypCfg, uint32_t direction_bitmap,
322 CSL_SERDES_MAX_LANES, serdes_init_params.lane_mask, 323 CSL_SERDES_MAX_LANES, serdes_init_params.lane_mask,
323 serdes_init_params.phy_type); 324 serdes_init_params.phy_type);
324 325
325 if(csl_retval) { 326 if(csl_retval && !(direction_bitmap & SERDES_DIRECTION_RX_RESET)) {
326 /* exit with success */ 327 /* exit with success */
327 return 0; 328 return 0;
328 } 329 }
@@ -345,7 +346,8 @@ int hyplnkSerdesSetup(mpm_transport_hyplnk_t *hypCfg, uint32_t direction_bitmap,
345 } while ((lane_retval != CSL_SERDES_LANE_ENABLE_NO_ERR)); 346 } while ((lane_retval != CSL_SERDES_LANE_ENABLE_NO_ERR));
346 if (lane_retval != CSL_SERDES_LANE_ENABLE_NO_ERR) 347 if (lane_retval != CSL_SERDES_LANE_ENABLE_NO_ERR)
347 { 348 {
348 mpm_printf (1, "Invalid Serdes Lane Enable Init\n"); 349 mpm_printf (1, "Invalid Serdes Lane Enable Init. lane_retval=%d\n",
350 lane_retval);
349 goto error_return; 351 goto error_return;
350 } 352 }
351 } 353 }
@@ -394,7 +396,6 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
394 int ecc_error_occurred = 0; 396 int ecc_error_occurred = 0;
395 397
396 sem_init(&hyperlink_sem[index], 0, 1); 398 sem_init(&hyperlink_sem[index], 0, 1);
397 bool rxSerdesInit=FALSE;
398 399
399 /* To prove the APIs work -- expose uninitialized variables */ 400 /* To prove the APIs work -- expose uninitialized variables */
400 memset (&rev, 0xff, sizeof(rev)); 401 memset (&rev, 0xff, sizeof(rev));
@@ -442,7 +443,7 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
442 return retVal; 443 return retVal;
443 } 444 }
444 445
445 /* Read rev and control */ 446 /* Read all regs */
446 if ((retVal = Hyplnk_readRegs (handle, hyplnk_LOCATION_LOCAL, &getRegs)) != hyplnk_RET_OK) { 447 if ((retVal = Hyplnk_readRegs (handle, hyplnk_LOCATION_LOCAL, &getRegs)) != hyplnk_RET_OK) {
447 mpm_printf(1, "Read revision register failed!\n"); 448 mpm_printf(1, "Read revision register failed!\n");
448 return retVal; 449 return retVal;
@@ -450,6 +451,9 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
450 451
451 if (reset) 452 if (reset)
452 { 453 {
454 memset (&setRegs, 0, sizeof(setRegs));
455 setRegs.control = &control;
456
453 /* if we need to stop serial traffic */ 457 /* if we need to stop serial traffic */
454 /* Stop traffic before reset */ 458 /* Stop traffic before reset */
455 control.serialStop = 1; 459 control.serialStop = 1;
@@ -458,6 +462,9 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
458 return retVal; 462 return retVal;
459 } 463 }
460 464
465 memset (&getRegs, 0, sizeof(getRegs));
466 getRegs.status = &status;
467
461 /* Wait for traffic to stop */ 468 /* Wait for traffic to stop */
462 for (i = 0; i < timeout; i++) { 469 for (i = 0; i < timeout; i++) {
463 if ((retVal = Hyplnk_readRegs (handle, hyplnk_LOCATION_LOCAL, &getRegs)) != hyplnk_RET_OK) { 470 if ((retVal = Hyplnk_readRegs (handle, hyplnk_LOCATION_LOCAL, &getRegs)) != hyplnk_RET_OK) {
@@ -470,6 +477,13 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
470 usleep(1000); 477 usleep(1000);
471 } 478 }
472 479
480 memset (&setRegs, 0, sizeof(setRegs));
481 setRegs.control = &control;
482 setRegs.status = &status;
483 setRegs.ECCErrors = &ECCErrors;
484 setRegs.lanePwrMgmt = &lanePwrMgmt;
485 setRegs.serdesControl1 = &serdesControl1;
486
473 /* Reset the peripheral */ 487 /* Reset the peripheral */
474 control.reset = 1; 488 control.reset = 1;
475 status.lError = 1; /* Clear any error */ 489 status.lError = 1; /* Clear any error */
@@ -496,11 +510,10 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
496 if (hyplnkActiveIF[index].slavesActive == 1) { 510 if (hyplnkActiveIF[index].slavesActive == 1) {
497 if (hypCfg->serdesInit) { 511 if (hypCfg->serdesInit) {
498 512
499 /* Don't need to clear any more status bits */ 513 memset (&setRegs, 0, sizeof(setRegs));
500 setRegs.status = NULL; 514
501 setRegs.ECCErrors = NULL; 515 setRegs.control = &control;
502 setRegs.lanePwrMgmt = NULL; 516 setRegs.TXAddrOvly = &TXAddrOvly;
503 setRegs.serdesControl1 = NULL;
504 517
505 TXAddrOvly.txSecOvl = 0; 518 TXAddrOvly.txSecOvl = 0;
506 TXAddrOvly.txPrivIDOvl = hypCfg->hyplnkTxPrivID; 519 TXAddrOvly.txPrivIDOvl = hypCfg->hyplnkTxPrivID;
@@ -537,9 +550,17 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
537 return retVal; 550 return retVal;
538 } 551 }
539 552
553 memset (&getRegs, 0, sizeof(getRegs));
554
555 getRegs.status = &status;
556 getRegs.linkStatus = &linkStatus;
557 getRegs.ECCErrors = &ECCErrors;
558
540 /* Prepare structure for setErrorRegs */ 559 /* Prepare structure for setErrorRegs */
541 memset (&setErrorRegs, 0, sizeof(setErrorRegs)); 560 memset (&setErrorRegs, 0, sizeof(setErrorRegs));
542 setErrorRegs.ECCErrors = &ECCErrors; 561 setErrorRegs.ECCErrors = &ECCErrors;
562 setErrorRegs.status = &status;
563 setErrorRegs.control = &control;
543 564
544 i=0; 565 i=0;
545 do 566 do
@@ -554,9 +575,39 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
554 ecc_error_occurred++; 575 ecc_error_occurred++;
555 576
556 /* If error found reset error and try again */ 577 /* If error found reset error and try again */
578
579 control.reset = 1;
580 control.serialStop = 1;
581 status.lError = 1; /* Clear any error */
582 status.rError = 1; /* Clear any error */
557 ECCErrors.sglErrCor = 0; 583 ECCErrors.sglErrCor = 0;
558 ECCErrors.dblErrDet = 0; 584 ECCErrors.dblErrDet = 0;
559 if ((retVal = Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL, 585
586 /* Set Reset, serial stop hyplnk and reset errors */
587 if ((retVal = Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL,
588 &setErrorRegs)) != hyplnk_RET_OK) {
589 mpm_printf(1, "Error register write failed!\n");
590 return retVal;
591 }
592
593 /* Bring hyperlink out of reset */
594 control.reset = 0;
595 if ((retVal = Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL,
596 &setErrorRegs)) != hyplnk_RET_OK) {
597 mpm_printf(1, "Error register write failed!\n");
598 return retVal;
599 }
600
601 /* Reinitialize serdes Rx */
602 if (hyplnkSerdesSetup(hypCfg,
603 SERDES_DIRECTION_RX | SERDES_DIRECTION_RX_RESET,
604 timeout) == -1) {
605 mpm_printf(1, "Failed to setup serdes for hyperlink 0\n");
606 return -1;
607 }
608
609 control.serialStop = 0;
610 if ((retVal = Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL,
560 &setErrorRegs)) != hyplnk_RET_OK) { 611 &setErrorRegs)) != hyplnk_RET_OK) {
561 mpm_printf(1, "Error register write failed!\n"); 612 mpm_printf(1, "Error register write failed!\n");
562 return retVal; 613 return retVal;
@@ -578,15 +629,13 @@ hyplnkRet_e hyplnkPeripheralSetup (mpm_transport_hyplnk_t *hypCfg, int index,
578 return retVal; 629 return retVal;
579 } 630 }
580 631
581 if (ecc_error_occurred) {
582 mpm_printf(1, "Ecc error occurred...%d\n", ecc_error_occurred);
583 /* TODO: returning error to see if ECC occurring */
584 return hyplnk_RET_INV_INITCFG;
585 }
586
587 if (!(interface_mode) && (i >= timeout) && (timeout != 0)) 632 if (!(interface_mode) && (i >= timeout) && (timeout != 0))
588 { 633 {
589 mpm_printf(1, "Timeout exceeded for connection, exiting...\n"); 634 mpm_printf(1, "Timeout exceeded for connection, exiting...\n");
635 mpm_printf(1,
636 "Timeout: (status.link=%d) (status.serialHalt=%d) (status.pllUnlock=%d) (linkStatus.txRSync=%d) (linkStatus.txPlsOK=%d) (ecc_error_occurred=%d)...\n",
637 status.link, status.serialHalt, status.pllUnlock, linkStatus.txRSync,
638 linkStatus.txPlsOK, ecc_error_occurred);
590 return hyplnk_RET_INV_INITCFG; 639 return hyplnk_RET_INV_INITCFG;
591 } 640 }
592 641
@@ -738,7 +787,6 @@ int mpm_transport_hyplnk_reset(mpm_transport_hyplnk_t *hypCfg, int index)
738 } 787 }
739 } while(setRegs.status->rPend); 788 } while(setRegs.status->rPend);
740 789
741 control.serialStop = 0;
742 control.reset = 1; 790 control.reset = 1;
743 if ((retVal = Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL, &setRegs)) != hyplnk_RET_OK) { 791 if ((retVal = Hyplnk_writeRegs (handle, hyplnk_LOCATION_LOCAL, &setRegs)) != hyplnk_RET_OK) {
744 mpm_printf(1, "Control register write failed!\n"); 792 mpm_printf(1, "Control register write failed!\n");