diff options
Diffstat (limited to 'drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c')
-rw-r--r-- | drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c | 81 |
1 files changed, 63 insertions, 18 deletions
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c index c2dadaa..7ce0a31 100644 --- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c +++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c @@ -1136,8 +1136,9 @@ static INT drop_tx_status_enabled(void) static INT config_sub_second_increment(ULONG ptp_clock) { - ULONG val; ULONG VARMAC_TCR; + double ss_inc = 0; + double sns_inc = 0; MAC_TCR_RGRD(VARMAC_TCR); @@ -1145,30 +1146,69 @@ static INT config_sub_second_increment(ULONG ptp_clock) /* formula is : ((1/ptp_clock) * 1000000000) */ /* where, ptp_clock = 50MHz if FINE correction */ /* and ptp_clock = DWC_ETH_QOS_SYSCLOCK if COARSE correction */ -#ifdef CONFIG_PPS_OUTPUT if (GET_VALUE(VARMAC_TCR, MAC_TCR_TSCFUPDT_LPOS, MAC_TCR_TSCFUPDT_HPOS) == 1) { EMACDBG("Using PTP clock %ld MHz\n", ptp_clock); - val = ((1 * 1000000000ull) / ptp_clock); + ss_inc = (double)1000000000.0 / (double)ptp_clock; } else { EMACDBG("Using SYSCLOCK for coarse correction\n"); - val = ((1 * 1000000000ull) / DWC_ETH_QOS_SYSCLOCK ); + ss_inc = (double)1000000000.0 / (double)DWC_ETH_QOS_SYSCLOCK; } -#else - if (GET_VALUE(VARMAC_TCR, MAC_TCR_TSCFUPDT_LPOS, MAC_TCR_TSCFUPDT_HPOS) == 1) { - val = ((1 * 1000000000ull) / 50000000); - } - else { - val = ((1 * 1000000000ull) / ptp_clock); - } -#endif - /* 0.465ns accurecy */ + + /* 0.465ns accuracy */ if (GET_VALUE( VARMAC_TCR, MAC_TCR_TSCTRLSSR_LPOS, - MAC_TCR_TSCTRLSSR_HPOS) == 0) - val = (val * 1000) / 465; + MAC_TCR_TSCTRLSSR_HPOS) == 0) { + EMACDBG("using 0.465 ns accuracy"); + ss_inc /= 0.465; + } + + sns_inc = ss_inc - (int)ss_inc; // take remainder + sns_inc *= 256.0; // sns_inc needs to be multiplied by 2^8, per spec. + sns_inc += 0.5; // round to nearest int value. - MAC_SSIR_SSINC_UDFWR(val); + MAC_SSIR_SSINC_UDFWR((int)ss_inc); + MAC_SSIR_SNSINC_UDFWR((int)sns_inc); + EMACDBG("ss_inc = %d, sns_inc = %d\n", (int)ss_inc, (int)sns_inc); + + return Y_SUCCESS; + } +/*! + * \brief + * \param[in] + * \return Success or Failure + * \retval 0 Success + * \retval -1 Failure + */ + +static INT config_default_addend(struct DWC_ETH_QOS_prv_data *pdata, ULONG ptp_clock) +{ + struct hw_if_struct *hw_if = &pdata->hw_if; + u64 temp; + + /* formula is : + * addend = 2^32/freq_div_ratio; + * + * where, freq_div_ratio = DWC_ETH_QOS_SYSCLOCK/50MHz + * + * hence, addend = ((2^32) * 50MHz)/DWC_ETH_QOS_SYSCLOCK; + * + * NOTE: DWC_ETH_QOS_SYSCLOCK should be >= 50MHz to + * achive 20ns accuracy. + * + * 2^x * y == (y << x), hence + * 2^32 * 50000000 ==> (50000000 << 32) + */ + if (ptp_clock == DWC_ETH_QOS_SYSCLOCK) { + // If PTP_CLOCK == SYS_CLOCK, best we can do is 2^32 - 1 + pdata->default_addend = 0xFFFFFFFF; + } else { + temp = (u64)((u64)ptp_clock << 32); + pdata->default_addend = div_u64(temp, DWC_ETH_QOS_SYSCLOCK); + } + hw_if->config_addend(pdata->default_addend); + EMACDBG("PPS: PTPCLK_Config: freq=%dHz, addend_reg=0x%x\n", + ptp_clock, (unsigned int)pdata->default_addend); return Y_SUCCESS; } @@ -4795,8 +4835,6 @@ static INT DWC_ETH_QOS_yinit(struct DWC_ETH_QOS_prv_data *pdata) for (QINX = 0; QINX < DWC_ETH_QOS_TX_QUEUE_CNT; QINX++) configure_mtl_queue(QINX, pdata); - /* Mapping MTL Rx queue and DMA Rx channel. */ - MTL_RQDCM0R_RGWR(0x3020100); #ifdef DWC_ETH_QOS_CERTIFICATION_PKTBURSTCNT /* enable tx drop status */ MTL_OMR_DTXSTS_UDFWR(0x1); @@ -4805,6 +4843,12 @@ static INT DWC_ETH_QOS_yinit(struct DWC_ETH_QOS_prv_data *pdata) configure_mac(pdata); configure_dma_sys_bus(pdata); + /* Mapping MTL Rx queue and DMA Rx channel. */ + if (pdata->res_data->early_eth_en) + MTL_RQDCM0R_RGWR(0x3020101); + else /* Mapped RX queue 0 to DMA channel 1 */ + MTL_RQDCM0R_RGWR(0x3020100); + for (QINX = 0; QINX < DWC_ETH_QOS_TX_QUEUE_CNT; QINX++) { if (pdata->ipa_enabled && QINX == IPA_DMA_TX_CH) continue; @@ -5110,6 +5154,7 @@ void DWC_ETH_QOS_init_function_ptrs_dev(struct hw_if_struct *hw_if) /* for hw time stamping */ hw_if->config_hw_time_stamping = config_hw_time_stamping; hw_if->config_sub_second_increment = config_sub_second_increment; + hw_if->config_default_addend = config_default_addend; hw_if->init_systime = init_systime; hw_if->config_addend = config_addend; hw_if->adjust_systime = adjust_systime; |