Commit 166367ea authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

hal: fixes in the calibration logic

- load the cal file at the right moment (prior to startup of the FSMs)
- increase phase tollerance for the first time calibration (some bins are missing on some transceivers, therefore aiming for just one is risky)
- added timeout & retry on rt_ipc communication (likely masks a bug in mini-rpc)
parent 7f4a59f7
......@@ -43,6 +43,13 @@
#define UPDATE_SFP_DOM_PERIOD 1000 /* ms */
#define LINK_LED_BLINK_PERIOD 200 /* ms */
#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 struct {
struct pp_instance * ppi; /* pointer to the ppi instance */
struct pp_servo servo_snapshot; /* image of a the ppsi servo */
......@@ -64,6 +71,7 @@ struct hal_port_tx_setup_state
int tollerance;
int update_cnt;
int expected_phase_valid;
timeout_t timeout;
};
/* Low Phase Drift Calibration for rx */
......@@ -350,7 +358,6 @@ int hal_port_init_shmem(char *logfilename)
return -1;
}
load_tx_calibration_file();
hal_shmem->ports = ports;
......@@ -358,6 +365,8 @@ int hal_port_init_shmem(char *logfilename)
if (hal_port_init(index) < 0)
break;
load_tx_calibration_file();
hal_port_nports = index;
pr_info("Number of physical ports supported in HW: %d\n",
......@@ -1104,7 +1113,7 @@ static void tx_fsm_init(struct hal_port_state *p)
fsm->state = TX_SETUP_STATE_START;
fsm->expected_phase = 0;
fsm->expected_phase_valid = 0;
fsm->tollerance = 300;
fsm->tollerance = TX_CAL_TOLLERANCE;
fsm->update_cnt = 0;
fsm->cal_saved_phase_valid = 0;
fsm->cal_saved_phase = 0;
......@@ -1120,7 +1129,7 @@ static int within_range(int x, int minval, int maxval, int wrap)
{
int rv;
printf("min %d max %d x %d ", minval, maxval, x);
//printf("min %d max %d x %d ", minval, maxval, x);
while (maxval >= wrap)
maxval -= wrap;
......@@ -1172,7 +1181,7 @@ static void update_tx_calibration_file(void)
if (file_exists(calibration_file_name))
{
//pr_info("TX phase calibration data already exists, no need to update\n");
pr_info("TX phase calibration data already exists, no need to update\n");
return;
}
......@@ -1293,12 +1302,21 @@ static int tx_fsm_update(struct hal_port_state *p)
rts_enable_ptracker(p->hw_index, 1);
tx_fsm_pll_state.channels[p->hw_index].flags = 0;
libwr_tmo_init(&fsm->timeout, TX_CAL_PHASE_MEAS_TIMEOUT, 1);
}
break;
}
case TX_SETUP_STATE_MEASURE_PHASE:
{
if (libwr_tmo_expired(&fsm->timeout) )
{
pr_info("Port %d: tx phase measurement timeout expired, retrying\n", p->hw_index+1);
fsm->state = TX_SETUP_STATE_RESET_PCS;
return 0;
}
if (!(tx_fsm_pll_state.channels[p->hw_index].flags & CHAN_PMEAS_READY))
return 0; // keep waiting
......@@ -1309,18 +1327,18 @@ static int tx_fsm_update(struct hal_port_state *p)
{
if (fsm->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", fsm->cal_saved_phase);
fsm->expected_phase = fsm->cal_saved_phase;
}
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
{
fsm->expected_phase = phi;
phi -= 800;
} while (phi > 0);
fsm->tollerance = TX_CAL_FIRST_CAL_TOLLERANCE;
fsm->expected_phase = TX_CAL_FIRST_CAL_EXPECTED_PHASE;
}
fsm->expected_phase_valid = 1;
}
......@@ -1501,14 +1519,11 @@ static int rx_fsm_update(struct hal_port_state *p)
MDIO_LPC_CTRL);
pcs_writel(p, BMCR_ANENABLE | BMCR_ANRESTART, MII_BMCR);
//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", p->hw_index + 1,
phase, fsm->attempts);
printf("MDIO_MCR %04x\n", pcs_readl(p, 0));
rts_enable_ptracker(p->hw_index, 0);
sleep(1);
printf("MDIO_MSR %04x\n", pcs_readl(p, 1));
sleep(1); // fixme: really needed?
}
break;
......@@ -1520,7 +1535,7 @@ static int rx_fsm_update(struct hal_port_state *p)
if (!(dbg0 & MDIO_LPC_STAT_LINK_UP))
{
pr_info("rxcal: port %d went down\n", p->hw_index + 1);
pr_info("rxcal: early link flag lost on port wri%d\n", p->hw_index + 1);
fsm->state = RX_SETUP_STATE_INIT;
return 0;
......
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