Commit 527ac628 authored by Maciej Lipinski's avatar Maciej Lipinski

[HAL] hand-imported Tom's commit (166367ea) "fixes in calibration logic"

- add timeout for tx calibration to overcome bugs in reading info from SoftPLL
- change initial calibration tolerance
- come changes in prints
parent 3d28b15e
...@@ -79,6 +79,7 @@ typedef struct { ...@@ -79,6 +79,7 @@ typedef struct {
int tollerance; int tollerance;
int update_cnt; int update_cnt;
int expected_phase_valid; int expected_phase_valid;
timeout_t calib_timeout;
}halPortLpdcTx_t; }halPortLpdcTx_t;
/* Low Phase Drift Calibration for rx */ /* Low Phase Drift Calibration for rx */
......
...@@ -261,15 +261,11 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew ...@@ -261,15 +261,11 @@ static int _hal_port_rx_setup_state_validate(void *vpfg, int eventMsk, int isNew
MDIO_LPC_CTRL); MDIO_LPC_CTRL);
pcs_writel(ps, BMCR_ANENABLE | BMCR_ANRESTART, MII_BMCR); pcs_writel(ps, BMCR_ANENABLE | BMCR_ANRESTART, MII_BMCR);
//TODO-ML: change to port name //TODO-ML: change to port name
pr_info("Port %d: RX calibration complete at phase %d " pr_info("wri%d: RX calibration complete at phase %d "
"ps (after %d attempts).\n", ps->hw_index + 1, phase, "ps (after %d attempts).\n", ps->hw_index + 1,
rxSetup->attempts); phase, rxSetup->attempts);
if ( pcs_readl(ps, 0, &value)>=0 )
printf("MDIO_MCR %04x\n", value);
rts_enable_ptracker(ps->hw_index, 0); rts_enable_ptracker(ps->hw_index, 0);
sleep(1); sleep(1); // fixme: really needed?
if ( pcs_readl(ps, 1, &value)>=0 )
printf("MDIO_MSR %04x\n", value);
_fireState(vpfg, HAL_PORT_RX_SETUP_STATE_DONE); _fireState(vpfg, HAL_PORT_RX_SETUP_STATE_DONE);
} }
...@@ -290,6 +286,8 @@ static int _hal_port_rx_setup_state_done(void *vpfg, int eventMsk, int isNewStat ...@@ -290,6 +286,8 @@ static int _hal_port_rx_setup_state_done(void *vpfg, int eventMsk, int isNewStat
if ( ps->lpdc.isSupported ) { if ( ps->lpdc.isSupported ) {
if ( !_isHalRxSetupEventEarlyLinkUp(eventMsk)) { if ( !_isHalRxSetupEventEarlyLinkUp(eventMsk)) {
// Port went done // Port went done
pr_info("rxcal: early link flag lost on port wri%d\n",
ps->hw_index + 1);
_fireState(vpfg, HAL_PORT_RX_SETUP_STATE_START); _fireState(vpfg, HAL_PORT_RX_SETUP_STATE_START);
return 0; return 0;
} }
......
...@@ -138,7 +138,7 @@ static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewSta ...@@ -138,7 +138,7 @@ static int _hal_port_tx_setup_state_start(void *vpfg, int eventMsk, int isNewSta
txSetup->attempts=0; txSetup->attempts=0;
txSetup->expected_phase = 0; txSetup->expected_phase = 0;
txSetup->expected_phase_valid = 0; txSetup->expected_phase_valid = 0;
txSetup->tollerance = 300; txSetup->tollerance = TX_CAL_TOLLERANCE;
txSetup->update_cnt = 0; txSetup->update_cnt = 0;
_pll_state.channels[ps->hw_index].flags = 0; _pll_state.channels[ps->hw_index].flags = 0;
...@@ -184,6 +184,7 @@ static int _hal_port_tx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe ...@@ -184,6 +184,7 @@ static int _hal_port_tx_setup_state_reset_pcs(void *vpfg, int eventMsk, int isNe
*/ */
static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNewState) { static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps; struct hal_port_state * ps=((halPortFsmGen_t *)vpfg)->ps;
halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
uint32_t value; uint32_t value;
if ( pcs_readl(ps, MDIO_LPC_STAT,&value)>=0 ) { if ( pcs_readl(ps, MDIO_LPC_STAT,&value)>=0 ) {
...@@ -191,7 +192,9 @@ static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNe ...@@ -191,7 +192,9 @@ static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNe
ps->lpdc.txSetup->attempts++; ps->lpdc.txSetup->attempts++;
rts_enable_ptracker(ps->hw_index, 1); rts_enable_ptracker(ps->hw_index, 1);
_pll_state.channels[ps->hw_index].flags = 0; _pll_state.channels[ps->hw_index].flags = 0;
libwr_tmo_init(&txSetup->calib_timeout,
TX_CAL_PHASE_MEAS_TIMEOUT, 1);
_fireState(vpfg,HAL_PORT_TX_SETUP_STATE_MEASURE_PHASE); _fireState(vpfg,HAL_PORT_TX_SETUP_STATE_MEASURE_PHASE);
} }
} }
...@@ -205,11 +208,19 @@ static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNe ...@@ -205,11 +208,19 @@ static int _hal_port_tx_setup_state_wait_lock(void *vpfg, int eventMsk, int isNe
*/ */
static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int isNewState) { static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int isNewState) {
struct hal_port_state * ps = ((halPortFsmGen_t *) vpfg)->ps; struct hal_port_state * ps = ((halPortFsmGen_t *) vpfg)->ps;
halPortLpdcTx_t * txSetup; halPortLpdcTx_t *txSetup=ps->lpdc.txSetup;
updatePllState(ps); updatePllState(ps);
if (!(_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY)) if (!(_pll_state.channels[ps->hw_index].flags & CHAN_PMEAS_READY)) {
if (libwr_tmo_expired(&txSetup->calib_timeout) )
{
pr_info("Port %d: tx phase measurement timeout expired,"
" retrying\n", ps->hw_index+1);
_fireState(vpfg, HAL_PORT_TX_SETUP_STATE_RESET_PCS);
return 0; // retry
}
return 0; // keep waiting return 0; // keep waiting
}
txSetup = ps->lpdc.txSetup; txSetup = ps->lpdc.txSetup;
int phase = _pll_state.channels[ps->hw_index].phase_loopback; int phase = _pll_state.channels[ps->hw_index].phase_loopback;
...@@ -217,16 +228,17 @@ static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int ...@@ -217,16 +228,17 @@ static int _hal_port_tx_setup_state_measure_phase(void *vpfg, int eventMsk, int
if (!txSetup->expected_phase_valid) { if (!txSetup->expected_phase_valid) {
if (txSetup->cal_saved_phase_valid) { if (txSetup->cal_saved_phase_valid) {
// got calibration file already? Aim EXACTLY for the phase
// bin we used in the first calibration
pr_info("Using phase from file :%d\n", txSetup->cal_saved_phase); pr_info("Using phase from file :%d\n", txSetup->cal_saved_phase);
txSetup->expected_phase = txSetup->cal_saved_phase; txSetup->expected_phase = txSetup->cal_saved_phase;
} else { } else {
int phi = phase; // First time calibrating? Give ourselves some freedom,
// let's say the first 1.5 ns of the 16 ns ref clock
// cycle, so that we have enough setup time
do // find the phase bin right after the rising parallel clock edge txSetup->tollerance = TX_CAL_FIRST_CAL_TOLLERANCE;
{ txSetup->expected_phase = TX_CAL_FIRST_CAL_EXPECTED_PHASE;
txSetup->expected_phase = phi;
phi -= 800;
} while (phi > 0);
} }
txSetup->expected_phase_valid = 1; txSetup->expected_phase_valid = 1;
} }
...@@ -481,8 +493,6 @@ static int _within_range(int x, int minval, int maxval, int wrap) ...@@ -481,8 +493,6 @@ static int _within_range(int x, int minval, int maxval, int wrap)
{ {
int rv; int rv;
printf("min %d max %d x %d \n", minval, maxval, x);
while (maxval >= wrap) while (maxval >= wrap)
maxval -= wrap; maxval -= wrap;
......
...@@ -13,6 +13,13 @@ ...@@ -13,6 +13,13 @@
#include <libwr/wrs-msg.h> #include <libwr/wrs-msg.h>
#include "hal_port_gen_fsm.h" #include "hal_port_gen_fsm.h"
#define TX_CAL_PHASE_MEAS_TIMEOUT 1000 /* ms */
#define TX_CAL_TOLLERANCE 300 /* ps */
#define TX_CAL_FIRST_CAL_TOLLERANCE 750 /* ps */
#define TX_CAL_FIRST_CAL_EXPECTED_PHASE 750 /* ps */
typedef enum { typedef enum {
HAL_PORT_TX_SETUP_STATE_START=0, HAL_PORT_TX_SETUP_STATE_START=0,
HAL_PORT_TX_SETUP_STATE_RESET_PCS, HAL_PORT_TX_SETUP_STATE_RESET_PCS,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment