Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a8a02c9 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

net: stmmac: Add Flexible PPS support



This adds support for Flexible PPS output (which is equivalent
to per_out output of PTP subsystem).

Tested using an oscilloscope and the following commands:

1) Start PTP4L:
	# ptp4l -A -4 -H -m -i eth0 &
2) Set Flexible PPS frequency:
	# echo <idx> <ts> <tns> <ps> <pns> > /sys/class/ptp/ptpX/period

Where, ts/tns is start time and ps/pns is period time, and ptpX is ptp
of eth0.

Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Vitor Soares <soares@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9db9268f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -346,6 +346,8 @@ struct dma_features {
	/* TX and RX number of queues */
	unsigned int number_rx_queues;
	unsigned int number_tx_queues;
	/* PPS output */
	unsigned int pps_out_num;
	/* Alternate (enhanced) DESC mode */
	unsigned int enh_desc;
	/* TX and RX FIFO sizes */
+1 −0
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ enum power_event {
#define GMAC_HW_RXFIFOSIZE		GENMASK(4, 0)

/* MAC HW features2 bitmap */
#define GMAC_HW_FEAT_PPSOUTNUM		GENMASK(26, 24)
#define GMAC_HW_FEAT_TXCHCNT		GENMASK(21, 18)
#define GMAC_HW_FEAT_RXCHCNT		GENMASK(15, 12)
#define GMAC_HW_FEAT_TXQCNT		GENMASK(9, 6)
+1 −0
Original line number Diff line number Diff line
@@ -796,6 +796,7 @@ const struct stmmac_ops dwmac510_ops = {
	.safety_feat_irq_status = dwmac5_safety_feat_irq_status,
	.safety_feat_dump = dwmac5_safety_feat_dump,
	.rxp_config = dwmac5_rxp_config,
	.flex_pps_config = dwmac5_flex_pps_config,
};

int dwmac4_setup(struct stmmac_priv *priv)
+2 −0
Original line number Diff line number Diff line
@@ -373,6 +373,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
		((hw_cap & GMAC_HW_FEAT_RXQCNT) >> 0) + 1;
	dma_cap->number_tx_queues =
		((hw_cap & GMAC_HW_FEAT_TXQCNT) >> 6) + 1;
	/* PPS output */
	dma_cap->pps_out_num = (hw_cap & GMAC_HW_FEAT_PPSOUTNUM) >> 24;

	/* IEEE 1588-2002 */
	dma_cap->time_stamp = 0;
+55 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#include "dwmac4.h"
#include "dwmac5.h"
#include "stmmac.h"
#include "stmmac_ptp.h"

struct dwmac5_error_desc {
	bool valid;
@@ -494,3 +495,57 @@ int dwmac5_rxp_config(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
	writel(old_val, ioaddr + GMAC_CONFIG);
	return ret;
}

int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
			   struct stmmac_pps_cfg *cfg, bool enable,
			   u32 sub_second_inc, u32 systime_flags)
{
	u32 tnsec = readl(ioaddr + MAC_PPSx_TARGET_TIME_NSEC(index));
	u32 val = readl(ioaddr + MAC_PPS_CONTROL);
	u64 period;

	if (!cfg->available)
		return -EINVAL;
	if (tnsec & TRGTBUSY0)
		return -EBUSY;
	if (!sub_second_inc || !systime_flags)
		return -EINVAL;

	val &= ~PPSx_MASK(index);

	if (!enable) {
		val |= PPSCMDx(index, 0x5);
		writel(val, ioaddr + MAC_PPS_CONTROL);
		return 0;
	}

	val |= PPSCMDx(index, 0x2);
	val |= TRGTMODSELx(index, 0x2);
	val |= PPSEN0;

	writel(cfg->start.tv_sec, ioaddr + MAC_PPSx_TARGET_TIME_SEC(index));

	if (!(systime_flags & PTP_TCR_TSCTRLSSR))
		cfg->start.tv_nsec = (cfg->start.tv_nsec * 1000) / 465;
	writel(cfg->start.tv_nsec, ioaddr + MAC_PPSx_TARGET_TIME_NSEC(index));

	period = cfg->period.tv_sec * 1000000000;
	period += cfg->period.tv_nsec;

	do_div(period, sub_second_inc);

	if (period <= 1)
		return -EINVAL;

	writel(period - 1, ioaddr + MAC_PPSx_INTERVAL(index));

	period >>= 1;
	if (period <= 1)
		return -EINVAL;

	writel(period - 1, ioaddr + MAC_PPSx_WIDTH(index));

	/* Finally, activate it */
	writel(val, ioaddr + MAC_PPS_CONTROL);
	return 0;
}
Loading