summaryrefslogtreecommitdiff
path: root/drivers/emac-dwc-eqos
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/emac-dwc-eqos')
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c73
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c137
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_ptp.c5
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h5
4 files changed, 87 insertions, 133 deletions
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_dev.c
index b5facb6..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) / DWC_ETH_QOS_DEFAULT_PTP_CLOCK);
- }
- 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;
+ }
- MAC_SSIR_SSINC_UDFWR(val);
+ 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((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;
}
@@ -5114,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;
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
index b69ce6d..da0df86 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
@@ -4922,52 +4922,14 @@ static VOID DWC_ETH_QOS_config_timer_registers(
{
struct timespec now;
struct hw_if_struct *hw_if = &pdata->hw_if;
- u64 temp;
DBGPR("-->DWC_ETH_QOS_config_timer_registers\n");
+ pdata->ptpclk_freq = DWC_ETH_QOS_DEFAULT_PTP_CLOCK;
+ /* program default addend */
+ hw_if->config_default_addend(pdata, DWC_ETH_QOS_DEFAULT_PTP_CLOCK);
/* program Sub Second Increment Reg */
-#ifdef CONFIG_PPS_OUTPUT
- /* If default_addend is already programmed, then we expect that
- * sub_second_increment is also programmed already */
- if(pdata->default_addend == 0){
- hw_if->config_sub_second_increment(DWC_ETH_QOS_DEFAULT_PTP_CLOCK); // Using default 50MHz
- }
- else {
- u64 pclk;
- pclk = (u64) (pdata->default_addend) * DWC_ETH_QOS_SYSCLOCK;
- pclk += 0x8000000;
- pclk >>= 32;
- hw_if->config_sub_second_increment((u32)pclk);
- }
-#else
hw_if->config_sub_second_increment(DWC_ETH_QOS_DEFAULT_PTP_CLOCK);
-#endif
- /* 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)
- */
-#ifdef CONFIG_PPS_OUTPUT
- if(pdata->default_addend == 0){
- temp = (u64)((u64)DWC_ETH_QOS_DEFAULT_PTP_CLOCK << 32);
- pdata->default_addend = div_u64(temp, DWC_ETH_QOS_SYSCLOCK);
- EMACDBG("Using default PTP clock = 50MHz\n");
- }
-#else
- temp = (u64)((u64)DWC_ETH_QOS_DEFAULT_PTP_CLOCK << 32);
- pdata->default_addend = div_u64(temp, DWC_ETH_QOS_SYSCLOCK);
-#endif
- hw_if->config_addend(pdata->default_addend);
-
/* initialize system time */
getnstimeofday(&now);
hw_if->init_systime(now.tv_sec, now.tv_nsec);
@@ -5105,7 +5067,6 @@ static int ETH_PTPCLK_Config(struct DWC_ETH_QOS_prv_data *pdata, struct ifr_data
struct ETH_PPS_Config *eth_pps_cfg = (struct ETH_PPS_Config *)req->ptr;
struct hw_if_struct *hw_if = &pdata->hw_if;
int ret = 0;
- u64 val;
if ((eth_pps_cfg->ppsout_ch < 0) ||
(eth_pps_cfg->ppsout_ch >= pdata->hw_feat.pps_out_num))
@@ -5119,17 +5080,9 @@ static int ETH_PTPCLK_Config(struct DWC_ETH_QOS_prv_data *pdata, struct ifr_data
eth_pps_cfg->ptpclk_freq );
return -1;
}
+
pdata->ptpclk_freq = eth_pps_cfg->ptpclk_freq;
- val = (u64)(1ULL << 32);
- val = val * (eth_pps_cfg->ptpclk_freq);
- val += (DWC_ETH_QOS_SYSCLOCK/2);
- val = div_u64(val, DWC_ETH_QOS_SYSCLOCK);
- if ( val > 0xFFFFFFFF) val = 0xFFFFFFFF;
- EMACDBG("PPS: PTPCLK_Config: freq=%dHz, addend_reg=0x%x\n",
- eth_pps_cfg->ptpclk_freq, (unsigned int)val);
-
- pdata->default_addend = val;
- ret = hw_if->config_addend((unsigned int)val);
+ ret = hw_if->config_default_addend(pdata, (ULONG)eth_pps_cfg->ptpclk_freq);
ret |= hw_if->config_sub_second_increment( (ULONG)eth_pps_cfg->ptpclk_freq);
return ret;
@@ -5212,15 +5165,8 @@ void DWC_ETH_QOS_pps_timer_init(struct ifr_data_struct *req)
/* Enable timestamping. This is required to start system time generator.*/
MAC_TCR_TSENA_UDFWR(0x1);
-
- /* Configure MAC Sub-second and Sub-nanosecond increment register based on PTP clock. */
- MAC_SSIR_SSINC_UDFWR(0x4); // Sub-second increment value for 250MHz and 230.4MHz ptp clock
-
- MAC_SSIR_SNSINC_UDFWR(0x0); // Sub-nanosecond increment value for 250 MHz ptp clock
- EMACDBG("250 clock\n");
-
MAC_TCR_TSUPDT_UDFWR(0x1);
- MAC_TCR_TSCFUPDT_UDFWR(0x0); // Coarse Timestamp Update method.
+ MAC_TCR_TSCFUPDT_UDFWR(0x1); // Fine Timestamp Update method.
/* Initialize MAC System Time Update register */
MAC_STSUR_TSS_UDFWR(0x0); // MAC system time in seconds
@@ -5279,12 +5225,16 @@ int ETH_PPSOUT_Config(struct DWC_ETH_QOS_prv_data *pdata, struct ifr_data_struct
struct ETH_PPS_Config *eth_pps_cfg = (struct ETH_PPS_Config *)req->ptr;
unsigned int val;
int interval, width;
- int interval_ns; /*interval in nano seconds*/
+ struct hw_if_struct *hw_if = &pdata->hw_if;
- if (pdata->res_data->pps_lpass_conn_en &&
- eth_pps_cfg->ptpclk_freq <= 0) {
- /* Set PTP clock to default 250 */
- eth_pps_cfg->ptpclk_freq = DWC_ETH_QOS_DEFAULT_LPASS_CLOCK;
+ /* For lpass we need 19.2Mhz PPS frequency for PPS0.
+ If lpass is enabled don't allow to change the PTP clock
+ becuase if we change PTP clock then addend & subsecond increament
+ will change & We will not see 19.2Mhz for PPS0.
+ */
+ if (pdata->res_data->pps_lpass_conn_en ) {
+ eth_pps_cfg->ptpclk_freq = DWC_ETH_QOS_DEFAULT_PTP_CLOCK;
+ EMACDBG("using default ptp clock \n");
}
if ((eth_pps_cfg->ppsout_ch < 0) ||
@@ -5303,6 +5253,12 @@ int ETH_PPSOUT_Config(struct DWC_ETH_QOS_prv_data *pdata, struct ifr_data_struct
eth_pps_cfg->ppsout_duty = 99;
}
+ /* Configure increment values */
+ hw_if->config_sub_second_increment(eth_pps_cfg->ptpclk_freq);
+
+ /* Configure addent value as Fine Timestamp method is used */
+ hw_if->config_default_addend(pdata, eth_pps_cfg->ptpclk_freq);
+
if(0 < eth_pps_cfg->ptpclk_freq) {
pdata->ptpclk_freq = eth_pps_cfg->ptpclk_freq;
interval = (eth_pps_cfg->ptpclk_freq + eth_pps_cfg->ppsout_freq/2)
@@ -5323,14 +5279,6 @@ int ETH_PPSOUT_Config(struct DWC_ETH_QOS_prv_data *pdata, struct ifr_data_struct
EMACDBG("PPS: PPSOut_Config: interval=%d, width=%d\n", interval, width);
- if (pdata->res_data->pps_lpass_conn_en) {
- //calculate interval & width
- interval_ns = (1000000000/eth_pps_cfg->ppsout_freq) ;
- interval = ((interval_ns)/4) - 1;
- width = ((interval_ns)/(2*4)) - 1;
- EMACDBG("pps_interval=%d,width=%d\n",interval,width);
- }
-
switch (eth_pps_cfg->ppsout_ch) {
case DWC_ETH_QOS_PPS_CH_0:
if (pdata->res_data->pps_lpass_conn_en) {
@@ -5885,7 +5833,6 @@ static int DWC_ETH_QOS_handle_hwtstamp_ioctl(struct DWC_ETH_QOS_prv_data *pdata,
u32 ts_event_en = 0;
u32 av_8021asm_en = 0;
u32 VARMAC_TCR = 0;
- u64 temp = 0;
struct timespec now;
DBGPR_PTP("-->DWC_ETH_QOS_handle_hwtstamp_ioctl\n");
@@ -6056,47 +6003,11 @@ static int DWC_ETH_QOS_handle_hwtstamp_ioctl(struct DWC_ETH_QOS_prv_data *pdata,
hw_if->config_hw_time_stamping(VARMAC_TCR);
+ /* program default addend */
+ hw_if->config_default_addend(pdata, DWC_ETH_QOS_DEFAULT_PTP_CLOCK);
+
/* program Sub Second Increment Reg */
-#ifdef CONFIG_PPS_OUTPUT
- /* If default_addend is already programmed, then we expect that
- * sub_second_increment is also programmed already */
- if (pdata->default_addend == 0) {
- hw_if->config_sub_second_increment(DWC_ETH_QOS_DEFAULT_PTP_CLOCK); // Using default 50MHz
- } else {
- u64 pclk;
- pclk = (u64) (pdata->default_addend) * DWC_ETH_QOS_SYSCLOCK;
- pclk += 0x8000000;
- pclk >>= 32;
- hw_if->config_sub_second_increment((u32)pclk);
- }
-#else
hw_if->config_sub_second_increment(DWC_ETH_QOS_DEFAULT_PTP_CLOCK);
-#endif
- /* 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)
- *
- */
-#ifdef CONFIG_PPS_OUTPUT
- if(pdata->default_addend == 0){
- temp = (u64)((u64)DWC_ETH_QOS_DEFAULT_PTP_CLOCK << 32);
- pdata->default_addend = div_u64(temp, DWC_ETH_QOS_SYSCLOCK);
- EMACINFO("Using default PTP clock = 50MHz\n");
- }
-#else
- temp = (u64)((u64)DWC_ETH_QOS_DEFAULT_PTP_CLOCK << 32);
- pdata->default_addend = div_u64(temp, DWC_ETH_QOS_SYSCLOCK);
-#endif
- hw_if->config_addend(pdata->default_addend);
/* initialize system time */
getnstimeofday(&now);
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_ptp.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_ptp.c
index d47221b..1bcead3 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_ptp.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_ptp.c
@@ -318,9 +318,10 @@ int DWC_ETH_QOS_ptp_init(struct DWC_ETH_QOS_prv_data *pdata)
if (pdata->res_data->pps_lpass_conn_en) {
/*Configuring PPS0 PPS output frequency to defualt 19.2 Mhz*/
eth_pps_cfg.ppsout_ch = 0;
- eth_pps_cfg.ptpclk_freq = DWC_ETH_QOS_DEFAULT_LPASS_CLOCK;
- eth_pps_cfg.ppsout_freq = 19200000;
+ eth_pps_cfg.ptpclk_freq = DWC_ETH_QOS_DEFAULT_PTP_CLOCK;
+ eth_pps_cfg.ppsout_freq = DWC_ETH_QOS_DEFAULT_LPASS_PPS_FREQUENCY;
eth_pps_cfg.ppsout_start = 1;
+ eth_pps_cfg.ppsout_duty = 50;
req.ptr = (void*)&eth_pps_cfg;
DWC_ETH_QOS_pps_timer_init(&req);
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h b/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h
index 67fdd03..ee29121 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_yheader.h
@@ -427,8 +427,8 @@ extern void *ipc_emac_log_ctxt;
#define DWC_ETH_QOS_SYSCLOCK 250000000 /* System clock is 250MHz */
#define DWC_ETH_QOS_SYSTIMEPERIOD 4 /* System time period is 4ns */
-#define DWC_ETH_QOS_DEFAULT_PTP_CLOCK 50000000
-#define DWC_ETH_QOS_DEFAULT_LPASS_CLOCK 250000000
+#define DWC_ETH_QOS_DEFAULT_PTP_CLOCK 96000000
+#define DWC_ETH_QOS_DEFAULT_LPASS_PPS_FREQUENCY 19200000
#define DWC_ETH_QOS_TX_QUEUE_CNT (pdata->tx_queue_cnt)
#define DWC_ETH_QOS_RX_QUEUE_CNT (pdata->rx_queue_cnt)
@@ -1006,6 +1006,7 @@ struct hw_if_struct {
/* for hw time stamping */
INT(*config_hw_time_stamping)(UINT);
INT(*config_sub_second_increment)(unsigned long ptp_clock);
+ INT(*config_default_addend)(struct DWC_ETH_QOS_prv_data *pdata, unsigned long ptp_clock);
INT(*init_systime)(UINT, UINT);
INT(*config_addend)(UINT);
INT(*adjust_systime)(UINT, UINT, INT, bool);